Jump to content
dmsc

FastBasic 4.5 testing release

Recommended Posts

Hi All!

 

As @777ismyname said, I just published a test version for the new FastBasic release. Please, help me testing it so I can make a new release in time for the BASIC 10 liner contest :) 

 

There is a big new feature: parameters for the PROC/EXEC, like this example:

exec Test 1, 2
for i=1 to 4
  exec Test 5 - i, i
next

proc Test a b
  ? "Testing: "; a, b
endproc

Notice that in the EXEC the parameters are separated with commas,  but in the PROC the corresponding variables are separated with spaces. Also, the variables in the proc are not "local" like most languages, as all variables in FastBasic are global and the parameters are simply variables, the above code is basically equivalent to:

 

a=1 : b=2 : exec Test
for i=1 to 4
  a=5-1 : b=i : exec Test
next

proc Test
  ? "Testing: "; a, b
endproc

 

Also, in the Atari IDE the parser does not verify that the number of arguments passed to the EXEC is the same as received by the PROC, I plan to add a check to the floating-point version in a future version.

 

In addition to the above, there are other changes to the language:

- You can include arbitrary characters in string constants by using the hex value, like: PRINT "Hello"$9B"World" . So, now you can easily include he EOL character in strings directly, and in the cross compiler you can write Atari characters in strings simply by the ATASCII code.

- Added PAUSE without a parameter, this is the same as PAUSE 0, "wait for vsync".
- PROC has a shorter abbreviation: PR.,
- The parser is more robust to syntax errors, I discovered some erroneous inputs that could slow down the parser a lot.


Many improvements to the editor:

- Much faster COPY/PASTE operations,
- Restores left-margin value on exit to DOS,
- Remove P/M graphics when returning to the editor from user programs.

 

And improvements to the cross-compiler:

- Better error messages from some syntax errors, and fixes in parsing of big numbers.
- Check for PROC and EXEC parameters mismatch.
- An option to write an expanded and indented listing from an abbreviated listing, "-l"

 

Adding the support for PROC parameters while keeping the integer IDE under 8kb was a lot harder than expected, but I finally managed to squeeze a few bytes from the editor and made it fit, currently the "FBI.XEX" file is 8189 bytes!

 

As always, you can download the ATR, the manual and the cross-compiler from github: https://github.com/dmsc/fastbasic/releases/tag/v4.5-rc

 

I plan to do a few extra commits before the release, but nothing big.

 

Have Fun!

  • Like 6
  • Thanks 4

Share this post


Link to post
Share on other sites

...testing it now :) I am quickly becoming addicted to using the cross compiler. Later on on Sunday I plan on playing with the new PROCedure parameter passing.

 

Thank you so much for this awesome software, @dmsc!!!!!

 

Edit: Holy cow, the speedup on certain things using the cross compiler is amazing...

Edited by 777ismyname

Share this post


Link to post
Share on other sites

I did some tests...

 

I took my Patrol game source and parsed successfuly with the new FBI version. It does not have PROC subroutines, but it works OK... the best visual improvement is that no longer P/M garbage remains in the IDE when I press the BREAK key. The IDE feels better. Was the EFAST driver embedded in FBI? It is not included in the ATR.

 

BTW, I already submitted Patrol to the 2021 contest, and I won't change this game.

 

I hope this new FB version will be ready before the contest's deadline, because I'm moving my new game to the new syntax and features. These are my comments:

 

12 hours ago, dmsc said:

There is a big new feature: parameters for the PROC/EXEC

My new game has 3 PROCs which used some global variables to perform their tasks (no need to set up as parameters) and they also used a small set of global variables as temporary local ones (reused every time and everywhere). Only one of these PROCs required to set up a variable prior to the call, and it was great to remove that assignment and set it up as a parameter. This saved me some bytes of source code.

 

12 hours ago, dmsc said:

- PROC has a shorter abbreviation: PR.

This also saved me 3 bytes of source code (1 byte per PROC definition). What it could save me lots of bytes is that the EXEC statemente could be abbreviated as EX. This abbreviation is current assigned to EXIT, which is not being used as frecuently as I expected: 2 EXITs versus 17 EXECs. I guess that the new feature of parameters could increase the use of this calls.

 

12 hours ago, dmsc said:

- Added PAUSE without a parameter, this is the same as PAUSE 0, "wait for vsync".

This saved me another byte in the new game, but every of my games has at least one PAUSE with the zero.

 

12 hours ago, dmsc said:

the above code is basically equivalent to:

a=1 : b=2 : exec Test
for i=1 to 4
  a=5-1 : b=i : exec Test
next

proc Test
  ? "Testing: "; a, b
endproc

Shouldn't that line inside the FOR-NEXT loop be the following?

  a=5-i : b=i : exec Test

 

I did other experiments:

proc swap a b
endproc

a=1
b=2
? a,b
exec swap b,a
? a,b

... yes, it's an empty procedure, but it works!!! :)

 

13 hours ago, dmsc said:

in the Atari IDE the parser does not verify that the number of arguments passed to the EXEC is the same as received by the PROC

I tested this using my previous example, and I found some strange behaviors. The first time I added an EXEC with only one parameter, I got a 0 for one of the variables, but on the next run, when I added another EXEC but with a single literal, the 0 disappeared from the first print and moved to the new one. After I added some more EXECs, the zero no longer appeared. The latest test was passing 3 literals, and the result was unexpected: no swap, but got the 2nd and 3rd literals in order.

 

This is the full test case (the print was moved into the PROC):

PROC SWAP A B
? A,B
ENDPROC

A=1
B=2
? A,B

EXEC SWAP B,A
EXEC SWAP B
EXEC SWAP B,B
EXEC SWAP 1
EXEC SWAP 1,2
EXEC SWAP 1,2,3

The result was:

1         2        Default values
2         1        OK: Swapped
2         1        Not OK: A should be 1, B sould be anything (the first time it run was 0)
1         1        OK: took the 1 in B from the previous result
1         1        A is OK, B sould be anything (the first time it run was 0)
1         2        OK
2         3        A should be 1, B should be 2 (it took the latest parameters?)

As I got a zero when a parameter was missing but only sometimes, and as it seems to be taking the latest parameters when they are more, could it be memory corruption if this happens, for instance, inside a loop?

 

13 hours ago, dmsc said:

- You can include arbitrary characters in string constants by using the hex value, like: PRINT "Hello"$9B"World"

This is very useful. The EOL in the data strings issue is a problem I'm facing in my latest game, which I had to solve by manipulating the source data to remove them every time they appeared.

 

Thanks for the update. Let us know how it goes!!!

 

Share this post


Link to post
Share on other sites

Hi!

11 hours ago, vitoco said:

I did some tests...

 

I took my Patrol game source and parsed successfuly with the new FBI version. It does not have PROC subroutines, but it works OK... the best visual improvement is that no longer P/M garbage remains in the IDE when I press the BREAK key. The IDE feels better. Was the EFAST driver embedded in FBI? It is not included in the ATR.

No, in addition to the rewritten COPY/PASTE, the IDE has some minor optimizations, but EFAST is still included in the ATR - under the ">DOS>" folder - and you can load it manually for a much faster editing experience :) 

 

And yes, the new IDE disables P/M graphics when returning to the editor.

 

11 hours ago, vitoco said:

BTW, I already submitted Patrol to the 2021 contest, and I won't change this game.

 

I hope this new FB version will be ready before the contest's deadline, because I'm moving my new game to the new syntax and features. These are my comments:

 

My new game has 3 PROCs which used some global variables to perform their tasks (no need to set up as parameters) and they also used a small set of global variables as temporary local ones (reused every time and everywhere). Only one of these PROCs required to set up a variable prior to the call, and it was great to remove that assignment and set it up as a parameter. This saved me some bytes of source code.

 

This also saved me 3 bytes of source code (1 byte per PROC definition). What it could save me lots of bytes is that the EXEC statemente could be abbreviated as EX. This abbreviation is current assigned to EXIT, which is not being used as frecuently as I expected: 2 EXITs versus 17 EXECs. I guess that the new feature of parameters could increase the use of this calls.

 

I will probably change this if nobody else chimes in, it makes sense that the abbreviation to EXEC should be shorter. But, EXIT is also useful in all the loops...

 

11 hours ago, vitoco said:

This saved me another byte in the new game, but every of my games has at least one PAUSE with the zero.

Yes, I think that it makes sense that the "default" should be 0, as "PAUSE 0" does not sounds great (no pause? pause a little?), so "PAUSE" without parameters that means "wait for vertical blank" is a lot better.

 

11 hours ago, vitoco said:

Shouldn't that line inside the FOR-NEXT loop be the following?

  a=5-i : b=i : exec Test

Yes, a typo :P 

 

11 hours ago, vitoco said:

I did other experiments:

proc swap a b
endproc

a=1
b=2
? a,b
exec swap b,a
? a,b

... yes, it's an empty procedure, but it works!!! :)

This works because this is implemented using the interpreter stack: the "EXEC" reads the values of variable "B" and "A", and pushes both into the parameter stack, the "PROC" then reads the values and assigns them to the variables - this means that the values are swapped correctly. This could also be useful in other contexts where you need to update two variables, like  "EXEC SWAP A+B , A-B".

 

11 hours ago, vitoco said:

I tested this using my previous example, and I found some strange behaviors. The first time I added an EXEC with only one parameter, I got a 0 for one of the variables, but on the next run, when I added another EXEC but with a single literal, the 0 disappeared from the first print and moved to the new one. After I added some more EXECs, the zero no longer appeared. The latest test was passing 3 literals, and the result was unexpected: no swap, but got the 2nd and 3rd literals in order.

 

Well, you are calling into "undefined behavior" :) 

 

What happens is that the EXEC pushed a number of values into the stack and the PROC removed more values. It is expected that the first time, the extra removed value was 0 (as the stack starts at $480), but then the code would start to wrap around causing the values to be unpredictable. Also, the mismatch in number of parameters will result in an invalid stack position at the PROC exit. This will work in simple cases, as the stack is used for the interpreter to evaluate expressions and passing parameters - with one big exception: FOR loops keep the loop variable, step and limits in the stack, so if you put the "EXEC" inside a FOR loop in your examples the code will probably crash.

 

11 hours ago, vitoco said:

 

 

As I got a zero when a parameter was missing but only sometimes, and as it seems to be taking the latest parameters when they are more, could it be memory corruption if this happens, for instance, inside a loop?

Yes, the stack will wrap around - but as the location used by FastBasic ($480) is not used by the OS, this will be harmless to the system - except for the FOR loops mentioned above.

 

Thanks for all the tests!

 

Have Fun!

Share this post


Link to post
Share on other sites

Wow !! @dmsc thank You for still adding new features to this great basic implementation !! For me it's now best basic for Atari and I can't imagine what its gonna be in the future ! ;).

 

Thanks for You dedication and time put onto this. I'm sure many many people will use it and appreciate it :).

 

All good for You and all other members of this forum :).

  • Like 1

Share this post


Link to post
Share on other sites

@dmsc not sure if this is the right place to see if something is in development or being considered, but if so:

 

Do you have something in mind similar to the tbxl TEXT statement? Thinking a bit bigger, it would be cool to have a bit-blit routine that is not only capable of making big text in arbitrary colors/characters like TEXT, but also the ability to blit data from one memory location to another, including screen offsets (typically the width of lines), so instead of 8 move statements to get one character from character ram to a place on the screen you could do for example BLIT SRCADDR,WIDTH,OFFSET,HEIGHT,DESTADDR

That and a decent flood/scanline fill algorithm like PAINT would be handy graphics routines.

 

I get it if you can't fit it due to memory constraints.

  • Like 1

Share this post


Link to post
Share on other sites

Hi 0xC0FFEE!

 

34 minutes ago, OxC0FFEE said:

@dmsc not sure if this is the right place to see if something is in development or being considered, but if so:

Yes, IMHO, this is a good place to ask.

 

34 minutes ago, OxC0FFEE said:

Do you have something in mind similar to the tbxl TEXT statement?

Reason I don't have TEXT implemented is that the code is somewhat big - so I have put it behind other features.

 

In the meantime, If you don't care about code size (and speed!), you can get the effect with code like this:

' TEXT over graphics mode
GR.7

COLOR 3 : @TEXT 20, 15, &"HELLO WORLD!"
COLOR 2 : @TEXT 21, 16, &"HELLO WORLD!"

PROC TEXT X Y PTR
  FOR I=PTR+1 TO PTR+PEEK(PTR)
    Q=(PEEK(I) - 32) * 8 + PEEK(756)*256
    FOR YY=Y TO Y+7
      N=PEEK(Q) : INC Q
      FOR XX=X TO X+7
        IF N&128 THEN PLOT XX,YY
        N=N+N
      NEXT
    NEXT
    X=X+8
  NEXT
ENDPROC

(note in the example passing a string address to a procedure and then directly accessing the string by PEEK, this is "advanced usage")

 

34 minutes ago, OxC0FFEE said:

Thinking a bit bigger, it would be cool to have a bit-blit routine that is not only capable of making big text in arbitrary colors/characters like TEXT, but also the ability to blit data from one memory location to another, including screen offsets (typically the width of lines), so instead of 8 move statements to get one character from character ram to a place on the screen you could do for example BLIT SRCADDR,WIDTH,OFFSET,HEIGHT,DESTADDR

This is higher in my list of things to implement in FastBasic: a pair of screen "get" and "put" procedures, like the ones in GW-BASIC (and QBasic), this would allow doing soft-sprites. Problem is, this would also be large, as it would need support for each graphics mode (as using the OS functions would be too slow).

 

34 minutes ago, OxC0FFEE said:

That and a decent flood/scanline fill algorithm like PAINT would be handy graphics routines.

I don't plan on implementing flood fill, as the code is very large and IMHO, most uses of flood-fill can be realized by simply using the FILLTO and DRAWTO routines.

 

34 minutes ago, OxC0FFEE said:

I get it if you can't fit it due to memory constraints.

 

My goal is to always keep the integer-only version of the IDE under 8k (currently is 8169 bytes, just 23 bytes shorter than 8k). This is a very good way to not bloat the language and to be selective of which features are more important to have in a simple BASIC.

 

But, in the floating-point version I could add also the "extended" statements, perhaps limiting this expanded version under 10k (a reasonable goal).

 

Have Fun!

 

  • Like 3

Share this post


Link to post
Share on other sites

Thumbs up to everything you said. It's very reasonable. A clarification on this?

24 minutes ago, dmsc said:

This is higher in my list of things to implement in FastBasic: a pair of screen "get" and "put" procedures, like the ones in GW-BASIC (and QBasic), this would allow doing soft-sprites. Problem is, this would also be large, as it would need support for each graphics mode (as using the OS functions would be too slow).

What if you didn't even worry about what mode the screen was in and just let it be an implementation detail for the offset parameter? If you're in GR 8 then pass in 320, if mode 0 then it's 40. If you're using a wide-ass buffer and scrolling your screen horizontally around a larger buffer, set it to something higher to account for the full width. Am I making sense?

 

Essentially at a high abstraction:

BLIT(sourceaddr, width, height, destaddr[, offset]) {
  FOR Y=0 to height-1
    MOVE sourceaddr+offset*y, destaddr+offset*y, width
  NEXT Y
}

It's late, so please forgive me if I'm not thinking clearly and this is wrong or missing some detail.

Share this post


Link to post
Share on other sites

One other thing for tonight. I'm trying to wrap my head around switching my BASIC stuff to structured programming, and in your notes about switching to fastbasic (specifically about removing gotos) I find myself confused and really needing a few examples fleshed out (I would love it if each of the directives below had a short example)

 

When GOTO is used for a loop, replace with DO-LOOP.

 

IF THEN followed by multiple statements separated with COLONs (:) need to placed on separate lines, remove THEN and COLONs and add an ENDIF after where the last statement was on the line. FastBasic only skips the first statement following the THEN if the condition is false.

 

IF THEN GOTOs. If this creates a loop until condition, replace with REPEAT UNTIL (opposite condition) or WHILE WEND.

 

IF THEN GOTO bypass a chunk of code, test of opposite condition, and place an ENDIF when the GOTO destination was.

The program should be converted to the conventions of structured programming.

 

IF (Condition) THEN RETURN, or ENDPROC, Use, IF (Condition) THEN EXIT

 

IF (Condition) THEN GOTO pass RETURN with another RETURN... Replace RETURN with EXIT and last RETURN with ENDPROC or use IF ELSE ELIF ENDIF structure.

 

Kudos, again.

Share this post


Link to post
Share on other sites

Hi!

 

I did not write that wiki page, you can edit it to add further clarifications!

 

Bellow, some examples:

7 hours ago, OxC0FFEE said:

One other thing for tonight. I'm trying to wrap my head around switching my BASIC stuff to structured programming, and in your notes about switching to fastbasic (specifically about removing gotos) I find myself confused and really needing a few examples fleshed out (I would love it if each of the directives below had a short example)

 

When GOTO is used for a loop, replace with DO-LOOP.

Replace:

10 ? "HELLO"
20 GOTO 10

With:

DO
  ? "HELLO"
LOOP
7 hours ago, OxC0FFEE said:

IF THEN followed by multiple statements separated with COLONs (:) need to placed on separate lines, remove THEN and COLONs and add an ENDIF after where the last statement was on the line. FastBasic only skips the first statement following the THEN if the condition is false.

Replace:

A = 0
IF X THEN A=1 : X = 0 : ? "TEST"

With:

IF X
  A = 1
  X = 0
  ? "TEST"
ELSE
  A = 0
ENDIF
7 hours ago, OxC0FFEE said:

IF THEN GOTOs. If this creates a loop until condition, replace with REPEAT UNTIL (opposite condition) or WHILE WEND.

Replace:

10 A=10
20 ? "Line "; A
30 A=A-1
40 IF A > 0 THEN GOTO 20

With:

A=10
REPEAT
  ? "Line ";A
  A=A-1
UNTIL A<=0

s

7 hours ago, OxC0FFEE said:

IF THEN GOTO bypass a chunk of code, test of opposite condition, and place an ENDIF when the GOTO destination was.

The program should be converted to the conventions of structured programming.

 

IF (Condition) THEN RETURN, or ENDPROC, Use, IF (Condition) THEN EXIT

Replace:

10 A=1
20 GOSUB 100
30 END
100 ? "Procedure "; A
110 IF A < 0 THEN RETURN
120 ? "OK"
130 RETURN

With:

A=1
EXEC Example
END
PROC Example
  ? "Procedure "; A
  IF A<0 THEN EXIT
  ? "OK"
ENDPROC
7 hours ago, OxC0FFEE said:

IF (Condition) THEN GOTO pass RETURN with another RETURN... Replace RETURN with EXIT and last RETURN with ENDPROC or use IF ELSE ELIF ENDIF structure.

Replace:

10 A=1 : GOSUB 100
20 A=2 : GOSUB 100
30 END
100 ? "Proc ";A
110 IF A=1 THEN 140
120 ? "A=";A
130 RETURN
140 ? "SKIP"
150 RETURN

With:

A=1 : EXEC Tst
A=2 : EXEC Tst

PROC Tst
  ? "Proc ";A
  IF A<>1
    ? "A=";A
    EXIR
  ENDIF
  ? "SKIP"
ENDPROC

 

Have Fun!

 

  • Thanks 2

Share this post


Link to post
Share on other sites

With regards to the requests for extra commands on here, such as text, blit etc, I think that there could be an alternative way to go forwards on this. I was wondering what your thoughts are?

 

There will always be requests, for this, that or the other and you have limited space to fit things into.

 

What if we forget about the requirements of people writing the code in the IDE on the Atari and instead facilitate it to make it easier for those who are cross-compiling?

 

The concept is, there could be a nice interface between FastBasic and extension libraries. This would then make it simple for machine language coders to interface with FastBasic.

 

So instead of code like this which could be a fast plotting routine for example (yes, I know plot already exists :) ):

 

X=5

Y=10

C=12

X=USR(1536) ' This is rather cryptic... what is this calling?

 

We could have something like....

LibraryCommand 1,"FastPlot",5,10,12 

 

At the start of the code, we might have something like:

UseLibrary 1,"FastGraphics.obj",1536

 

(Note that 'LibraryCommand' and 'UseLibrary' or whatever they are named would only be available for the cross-compiler)

 

And then if there was a standard that the libraries have to implement for reading the parameters (potentially even returning one or more return values), this will enable people to intermix FastBasic and extended commands. Think of it like an API for FastBasic.

 

What are your thoughts? Or is there a simpler way that I am missing?

 

 

Edited by snicklin

Share this post


Link to post
Share on other sites

I was thinking in something similar, but with a different approach, using procedures with local variables (or "exclusive global" variables) in a way that the procedure could be "enabled" if it is being used (and included in the XEX). To call it, just use "EXEC" (abbreviated "@") as usual.

 

If the procedure just starts a USR with the received parameters, the routine should be relocatable, or with the assembly source code to be compiled at parse time if the address has been defined in the pass.

 

Of course, this is for the cross-compiler, not an IDE feature.

 

To output values, just give variables "by reference" as parameters using ADR function (abbreviated "&"), or include a FUNCTION definition in the syntax to return a single value.

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites
41 minutes ago, vitoco said:

I was thinking in something similar, but with a different approach, using procedures with local variables (or "exclusive global" variables) in a way that the procedure could be "enabled" if it is being used (and included in the XEX). To call it, just use "EXEC" (abbreviated "@") as usual.

 

If the procedure just starts a USR with the received parameters, the routine should be relocatable, or with the assembly source code to be compiled at parse time if the address has been defined in the pass.

 

Of course, this is for the cross-compiler, not an IDE feature.

 

To output values, just give variables "by reference" as parameters using ADR function (abbreviated "&"), or include a FUNCTION definition in the syntax to return a single value.

I think that your method would also be good. And probably less work for DMSC. Maybe a little less user-friendly as you have to write the Procedures, but this is acceptable in my mind.

 

I guess that all that would need is some form of written definition of how parameters are passed in, how they need to be referenced in the library and a formal definition of your last sentence there.

 

I will tell you my background here. I am writing a Football (round ball variant) Management game. I am loving working on it but it is taking a long time and it is difficult to debug. As I have written it in a modular way, I want the new parts to be in FB, but with intensive parts of it to be in machine language. For handling menus, key presses etc, Assembly language is overkill. I only need fast routines when performing calculations or doing DLI's. If the interface between the two can be really good, I could see myself speeding up with my creation a hell of a lot.

Share this post


Link to post
Share on other sites

Another reason that I put forwards this idea is that I do not feel that there is enough 'social' coding on the Atari 8-bit.

 

That is, I would love people to be able to quickly develop new functionality and to be able to share it with the community.

 

For example, someone might have a webpage with a list of libraries, all with different qualities that interface with FB. Then you would download all those libraries that you want (or the compiler could reference those libraries from the code and then download them automatically at compile time if a hash has changed) and all you would need to do is to link them together with your FastBasic code.

 

Imagine this as an example....

include "http://ataricode.com/libraries/animalsounds.lib"

 

Then....

LibraryCommand 1,"PlaySound",2 'Frog

 

Maybe I am dreaming, but I could see it as definitely being possible. @dmsc apologies if I am dreaming too much, I am not trying to create extra work for you, but I just want to express what I see as the most perfect development environment (without making it way too unrealistic). I believe it to be a compliment to the job that you have already done. If you do not agree with anything we say, it's OK, it's your product not ours.

 

  • Like 1

Share this post


Link to post
Share on other sites

yeah, I think a way to bring object code libraries in and call named entry points would be handy....one thing, though, wouldn't relocation have to be handled? Either relocation or some sized area would have to be set aside I would think.

 

Relocation is not all that hard, FB could specify a load format (obj prefaced with a relocation table, for instance). Actually I suppose a symbol table would be handy too, just like a real .dll or .so.

So It'd be something like:

 

[relocation table]

[symbol table]

[object code]

 

Edited by danwinslow

Share this post


Link to post
Share on other sites

Hi!

 

9 hours ago, snicklin said:

With regards to the requests for extra commands on here, such as text, blit etc, I think that there could be an alternative way to go forwards on this. I was wondering what your thoughts are?

 

There will always be requests, for this, that or the other and you have limited space to fit things into.

 

What if we forget about the requirements of people writing the code in the IDE on the Atari and instead facilitate it to make it easier for those who are cross-compiling?

 

The concept is, there could be a nice interface between FastBasic and extension libraries. This would then make it simple for machine language coders to interface with FastBasic.

 

So instead of code like this which could be a fast plotting routine for example (yes, I know plot already exists :) ):

 

X=5

Y=10

C=12

X=USR(1536) ' This is rather cryptic... what is this calling?

 

We could have something like....

LibraryCommand 1,"FastPlot",5,10,12 

In the cross compiler, you already can write machine code routines and call them by name:

X=USR(@MyLibraryCode, 123, 456)

You need to write the assembly routine in a separate ASM file and pass it to the compiler command line.

 

I'm implementing another feature: compiling multiple files in the command line. Then, you can split you code, putting PROC in one file and calling from the other. The advantage is that the variables would be local to each file, so you won't have clashing variable names. Currently you can't do this because:

- PROC and EXEC are checked in the cross compiler for the argument count;

- Variables are numbered in the compiler - this will need a global variable numbering;

- You need to specify one entry point - my plan is to simply concatenate all the code, so you need to ensure that only one file has code outside PROCs.

 

This does not allow to have extended commands in machine language, for that I will need another plan. As  @vitoco said, a good syntax should be to reuse the EXEC support, the problem is that the compiler will need to know beforehand which routines are machine code, but this should be easy is we come up with a syntax for adding "libraries".

 

Now, what I'm not sure about is the divergence of the native compiled v/s cross compiler, I think the two dialects should be as similar as possible - I really want FastBasic to be a good language to program *in* the Atari.

 

9 hours ago, snicklin said:

At the start of the code, we might have something like:

UseLibrary 1,"FastGraphics.obj",1536

You don't need the address if the code is relocatable - I currently use CA65 exactly because the object files are relocatable. But, won't it be better if you simply accept an "ASM" file as parameter? Also, what is the "!" for?

 

My suggested syntax is:

' Imports fast-drawing code:
#IMPORT "draw.lib"

GR.8
COLOR 1
FOR I=0 TO 100
  @FastLine I,0,0,100-I
NEXT I

The assembly code should be like this:

	.export FB_FASTLINE

	' Use temporary variables from FastBasic interpreter:
	.importzp tmp1, tmp2, sptr
	' Access FastBasic Stack
	.import	stack_l, stack_h

    ' And also use ROW/COL from OS
	.include "atari.inc"

	.code
.proc FB_FASTLINE
	' Receive 4 parameters, in inverse order in the atack
    ' Calling convention is: AX : 16 bit register, last parameter.
    '                         Y : current stack pointer value,
    ' Other parametrs: in stack_l and stack_h, indexed by stack pointer.

	' Parameter 4: Y1
    sta     ROWCRS
	' Parameter 3: X1
    ldx     stack_l, y
    stx     COLCRS
    ldx     stack_h, y
    stx     COLCRS+1
    iny
	' Parameter 2: Y1
    ldx     stack_l, y
    stx     tmp2
    iny
	' Parameter 1: X'
    ldx     stack_l, y
    stx     tmp1
    ldx     stack_h, y
    stx     tmp1+1
    ' Remove parameters from stack
    iny
    sty sptr
    ' Call our machine code:
    jmp my_draw_line
.endproc

Note that the calling convention is not very easy, as you have to pop all arguments from the stack in turn (using about 10 bytes per parameter) One possible optimization is to make a PROC in basic that receives your parameters, writing them in ZP locations, or simply accessing the PROC variables from the machine code.

 

Have Fun!

Share this post


Link to post
Share on other sites

Ah that's cool. But I think he meant like separately developed object libraries. With the way you describe above, you would just have to share appropriately coded source instead of a precompiled object file.

Share this post


Link to post
Share on other sites

Hi!

11 minutes ago, danwinslow said:

Ah that's cool. But I think he meant like separately developed object libraries. With the way you describe above, you would just have to share appropriately coded source instead of a precompiled object file.

Not necessarily, you can share CC65 libraries (.lib) or object code (.o). Currently the FastBasic cross compiler distributes all it's libraries as one ".lib" with all the compiled code. The CC65 object code and libraries are fully relocatable.

 

Have Fun!

Share this post


Link to post
Share on other sites

An issue with live might be linking with libraries from different releases of the cc65 tools?

Different ways around that, maybe adopting a naming convention.

Share this post


Link to post
Share on other sites
1 hour ago, dmsc said:

This does not allow to have extended commands in machine language, for that I will need another plan. As  @vitoco said, a good syntax should be to reuse the EXEC support, the problem is that the compiler will need to know beforehand which routines are machine code, but this should be easy is we come up with a syntax for adding "libraries".

My proposal was to use only FastBasic libraries in the form of PROCs. If the routine is assembly, it must be wrapped by a PROC with the proper USR call. This might add some overhead, but it's for simplicity.

 

Share this post


Link to post
Share on other sites
3 hours ago, dmsc said:

Hi!

Not necessarily, you can share CC65 libraries (.lib) or object code (.o). Currently the FastBasic cross compiler distributes all it's libraries as one ".lib" with all the compiled code. The CC65 object code and libraries are fully relocatable.

 

Have Fun!

They are? Has CC65 changed drastically lately? Not sure what I'm missing here, but I had to write my own relocation routines to load externally created .o files at runtime, even when created using CA65. You seem to be saying it will all be compiled/linked together, which of course will 'relocate' it. I was talking about a dynamic linking system, such as .dll or .so. At any rate, I'm out, because I don't understand what either of you guys are actually talking about. Love FB though.

Edited by danwinslow

Share this post


Link to post
Share on other sites
7 hours ago, dmsc said:

Hi!

 

In the cross compiler, you already can write machine code routines and call them by name:

X=USR(@MyLibraryCode, 123, 456)

You need to write the assembly routine in a separate ASM file and pass it to the compiler command line.

Oh this is great, you have something already in place! If that first 123 parameter was a word/integer, how would the FastBasic know that it was that and not a byte?

Share this post


Link to post
Share on other sites
7 hours ago, dmsc said:

You don't need the address if the code is relocatable - I currently use CA65 exactly because the object files are relocatable. But, won't it be better if you simply accept an "ASM" file as parameter? Also, what is the "!" for?

 

I think you typo'd there, but it was a '1'. I was thinking that you might need to have a handle for each library. So that you could tell FB which library that you are referring to when trying to access "FastPlot" for example. I guess that with unique naming, this isn't an issue. But if people are sharing libraries online, in theory there could be one person who supplies a library that seems different to another library, but they both reimplement the same named command. For example, "FastLocate" might be in a text library, but could also be in a graphics library.

Share this post


Link to post
Share on other sites
7 hours ago, danwinslow said:

Ah that's cool. But I think he meant like separately developed object libraries. With the way you describe above, you would just have to share appropriately coded source instead of a precompiled object file.

Great point, I did yes, but then again, the answer that was supplied was a great way of moving forwards now, rather than waiting for a new release. 

Share this post


Link to post
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...