Jump to content

Prog8 language and compiler topic


desertfish
 Share

Recommended Posts

Posted (edited)

    "Is there a way to indicate that a variable is in use in a asmsub? "

There is currently no one great way to do that. There are a few work arounds though:

You can force the compiler to output the variable by adding a 'dummy' assignment to it so that it is flagged as used:

ubyte tmpvar
tmpvar = 0

This will generate some code for that assignment obviously but it's just 2 instructions.

You could use "%option force_output" in the block, but this prevents optimization for all other unused variables and subroutines in that block as well.

Finally if it's just a variable you use in the assembly code (and it needs no interfacing with prog8 code) you can use any standard assembly mechanism you like in the asm block for defining variables:  use free zero page locations, use cx16.r0 .... cx16.r15,  use " tmpvar  .byte 0",  etc.   Those handful of ZP_SCRATCH variables you discovered can be used too if you know what you're doing -- they often are destroyed if you call prog8 assembly library routines.

Edited by desertfish
Link to comment
Share on other sites

4 minutes ago, desertfish said:

Those handful of ZP_SCRATCH variables you discovered can be used too if you know what you're doing -- they often are destroyed if you call prog8 assembly library routines.

I basically assumed that it would be fine to use ZP_SCRATCH variables as long as I avoided calling any subroutines "In between" use. That seem to be correct then.

BTW, the main problem with using the various zero page location is that we won't know which are used by the code until after compile is done. Note that this isn't likely an especially serious challenge but it's sort of would belong in a block similar to "clobbers" (i.e that the compiler marks variable as "used" if it's listed for the asmsub).

Link to comment
Share on other sites

that is actually a problem I haven't thought about yet!   

It would be very hard to let the compiler check your assembly code for invalid usages of the ZP addresses it allocated.....    are you suggesting a dump of some sort of the zp locations it allocated? So that you can act on that manually?

Link to comment
Share on other sites

45 minutes ago, desertfish said:

It would be very hard to let the compiler check your assembly code for invalid usages of the ZP addresses it allocated.....    are you suggesting a dump of some sort of the zp locations it allocated? So that you can act on that manually?

Let me again state that this is probably a very minmal problem and it could be covered by expanding the documentation for asmsub a bit.

However, if you would like to add it to the compiler I suggest adding it to the asmsub declaration.

  asmsub get_low(ubyte value @A) uses (testvar) clobbers(Y) -> ubyte @A {
    %asm {{
      sta testvar
      lda #$0F
      and testvar
      tay
      lda tbl,y
      rts
    }}
I.e uses (testvar) (or something similar) just lets the compiler know that testvar is no longer a potential unused variable, even if there is no actual use in the assembly code. I assume you are parsing this line anyway to match call parameters.

 

Link to comment
Share on other sites

Posted (edited)

oh-- that's a somewhat simpler issue you're referring to now. What about tagging the actual variable declaration instead in prog8?

Something like:

volatile ubyte testvar

or

shared ubyte testvar

to indicate to the compiler that testvar is used elsewhere that it doesn't know about?

However, the question is: why would you even declare the variable in prog8 if your only use of it is inside an assembly block and not in any prog8 code (in this case, why not just define the variable inside the assembly block...)?

Edited by desertfish
Link to comment
Share on other sites

Posted (edited)
1 hour ago, desertfish said:

However, the question is: why would you even declare the variable in prog8 if your only use of it is inside an assembly block and not in any prog8 code (in this case, why not just define the variable inside the assembly block...)?

That's basically because I don't really know how to use the assembler (at least not yet), so I just went for the default program declaration the feels natural to me. It's at least 30 years ago since I last touched assembly language (and that was on M68000 systems). So I'm more or less starting over from scratch and haven't really gotten to the the more assembler manual yet. I have started reading up on the 6802 instruction set though. Not too hard to get a basic grasp of that given the small instruction set.

Edited by borgar
typo
  • Like 1
Link to comment
Share on other sites

I've just released a new 7.0-beta version of the compiler  https://github.com/irmen/prog8/releases/tag/v7.0-beta 

Most important changes are in the CommanderX16 target: we now target the upcoming "V39" of the cx16 emulator and roms.
Programs targeting the cx16 compiled with this new Prog8 version may no longer work on the previous version of the emulator.

Also the ``struct`` language feature has been removed.  (hence the new 7.0 major version because this breaks old programs that use this. Rewrite structs as separate variables).

Also the random number generator (used for rnd() etc) has been replaced by a slower but much better one.

Detailed change list will be added when this 7.0 version is finalized, which will probably be shortly after the "V39" of the commanderx16 is officially released as well.

Link to comment
Share on other sites

Ah, I'm looking forward to testing the new rnd function. I have noticed that I seemed to get noticable clustering patterns. I'll probably wait a new build of the emulator.

Link to comment
Share on other sites

Since I've been doing a bit more programming for my game I thought I should give a bit more feedback about Prog8. I've naturally come across a few things here and there that ideally would be "fixed", but generally I find Prog8 to be a nice and simple language to work in. Since we are working closer to "the metal" than I normally do I think the simple types and limited syntax makes perfect sense. I especially like how easy it's to integrate in assembly functions with the Prog8 code. Apart from the odd actual bug I think this is where I would really like to see a bit of improvement.

I've already mentioned the issue with variables only used in assembly being optimized away. I'd prefer to have these in the Prog8 part of the code for a few reasons. One is visibility, perhaps the variable is later needed in the Prog8 code. The other is that we don't really know where we can put this in standalone assembly since Prog8 program might put it's own variable in the same "space" (at least when using ZP variables). I've been using the workaround (having dummy assignments in other code) but think it would be more elegant to have a way to mark a variable as "used in assembly" so it's not optimized away.

I was also going to add a ticket about constants being removed in assembly output as well, but found that someone already have covered this (https://github.com/irmen/prog8/issues/22). I'd just like to add that I also think this would be nice.

I have found debugging a bit more of a hassle than in my "day work", but that has more to do with the emulator and the nature of the platform. Though when I struggled at worst (and finally did have a look at this using the debug option in the emulator) it turned out to be a emulator bug, at least that is what I believe (Keyboard NES controller emulation kicks off with all bits reversed).

Link to comment
Share on other sites

Posted (edited)
9 hours ago, borgar said:

generally I find Prog8 to be a nice and simple language to work in. Since we are working closer to "the metal" than I normally do I think the simple types and limited syntax makes perfect sense. I especially like how easy it's to integrate in assembly functions with the Prog8 code.

Thanks, I am glad it is proving to be useful for others too in the way I intended it.

9 hours ago, borgar said:

I've already mentioned the issue with variables only used in assembly being optimized away. I'd prefer to have these in the Prog8 part of the code for a few reasons.

As long as you're not using zeropage locations you should be just fine by "inlining"  .byte or .word  statements in your asm blocks to reserve some variables space:

%asm {{
    lda  variable
    rts
variable  .byte 99
}}
 

I'm still considering a feature of some sort to mark variables to not optimize them away as unused, though.

9 hours ago, borgar said:

constants being removed in assembly output

This hasn't been the case anymore since the 6.5-beta version at least, so you may want to upgrade to that (or even better the recently published 7.0-beta version)

9 hours ago, borgar said:

debugging a bit more of a hassle

Yeah I'm not sure if prog8 compiler can be of any help for this for the Cx16 emulator.   It does output symbol and breakpoint lists for the Vice C64 emulator, but these are useless for the cx16 emulator.

Thanks for the feedback!

Edited by desertfish
Link to comment
Share on other sites

Ok, so I have a questions about adding larger sets of data in Prog8. Since the byte/ubyte data structures are limited to 256 bytes I have so far just split data into multiple arrays. That works well enough for now. However, let's say I want to update a full screen (40x25 for C64, more for CX16). It gets awkward to split this up into many arrays. 

It looks like perhaps %asminclude might be something but it's not obvious how to use this. I created a file

screen.asm

which contains my screen data :

screen_char
    BYTE    $20, $20, $20 ....

and include this in a module

screen {
  %asminclude "screen.asm", "screen"
  ...
}

and attempt to get hold of this label with something like

uword ref = screen.screen_char

without any luck (I tried various with and without various prefixes). According to the doc I should have access to the labels. I expect I'm doing something wrong but without any examples I don't know how to use this beyond this. 

Link to comment
Share on other sites

Defining a label at block scope (outside a subroutine) is only possible since the 7.0-beta release of Prog8.

Either upgrade your compiler or stick to labels inside of subroutines for now  (you can still refer to those perfectly fine by prefixing them with the subroutine name)

Link to comment
Share on other sites

Posted (edited)
8 hours ago, desertfish said:

Also you can now mark a variable as 'shared' with assembly code elsewhere, to not have it optimized away if even if you're not using it in prog8 code:

    ubyte @shared asmvar

 

Nice!

I guess I have to jump over to the 7 real soon. I was waiting for an official release of the new XC16 emulator, but there are so many updates now I'd like to use. I can always test using VICE for a while.

Edited by borgar
Link to comment
Share on other sites

Posted (edited)

Yeah I expected a new emulator release for quite a while already...

That said, I suspect most of the programs compiled by the new beta version of prog8 can work on the V38 emulator just fine.   The V39 changes were mainly in the ram/rom banking and some register changes.  If your program doesn't use these it will likely still work on V38 of the emulator. 

(oh and I think the floating point rom routines were relocated so you can't use floats if you want to do this)

Edited by desertfish
  • Like 1
Link to comment
Share on other sites

3 hours ago, desertfish said:

That said, I suspect most of the programs compiled by the new beta version of prog8 can work on the V38 emulator just fine.   The V39 changes were mainly in the ram/rom banking and some register changes.  If your program doesn't use these it will likely still work on V38 of the emulator. 

And it turns out you are 100% correct here. For Petaxian the output from 7.0-beta compiler runs fine in the current compiler.

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...
Posted (edited)

I've just released a new 7.0-beta2 version of the compiler https://github.com/irmen/prog8/releases/tag/v7.0-beta2

This version will likely be very close to the final 7.0 release because I'm not considering adding or changing anything new from now on (except bug fixes).

Some of the most important fixes/changes since the previous beta release:

  • string encoding and string interning bug fixes
  • various compiler crashes fixed
  • %asminclude fixed (scopelabel argument removed as well)
  • repeat loop code gen optimized some more

Once again: the CommanderX16 target targets the upcoming "V39" of the cx16 emulator and roms.
Programs targeting the cx16 compiled with this new Prog8 version may no longer work on the previous version of the emulator (although if you're not using floating point and bank switching, they will likely still work)

Detailed change list will be added when this 7.0 version is finalized, which will probably be shortly after the "V39" of the commanderx16 is officially released as well.

Edited by desertfish
  • Like 4
Link to comment
Share on other sites

I have upgraded to BETA2 and Petaxian runs fine I can now use the Prog8 const from my assembly which is excellent.

However, I'm still struggling with figuring out how to import raw data. I.e. I want to add full screen char data either as binary or as asm code. AND access this from Prog8. All I basically need is a way to figure out the address to the first byte of this data. Right now I can not e.g. see any way that %asmbinary is even useful. You mentioned using a lable but I can't get this to work. This might not be a bad idea to add an example for this btw.

In any case I'm trying something like this:

main {

rawdata:
  %asmbinary "data.bin"

  sub start() {
    uword charPtr = &rawdata
    charPtr++ ; Only to prevent removal of variable during compile
  }
}

but get the following error

.\screen_test.asm:57:9: error: not defined ident '_rawdata'
        lda  #<_rawdata
               ^
.\screen_test.asm:43:1: note: searched in this object only
 start  .proc
 ^

Link to comment
Share on other sites

2 hours ago, desertfish said:

In the meantime, can you try to replace &rawdata with &main.rawdata ?

Using the namespace prefix gives me

.\screen_test.asm:57:9: error: not defined ident '_main'
        lda  #<_main.rawdata
               ^
.\screen_test.asm:43:1: note: searched in this object only

Link to comment
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.

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.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use