Jump to content
desertfish

Prog8 language and compiler topic

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

Share this post


Link to post
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).

Share this post


Link to post
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?

Share this post


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

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


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

Share this post


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

Share this post


Link to post
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).

Share this post


Link to post
Share on other sites
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

Share this post


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

Share this post


Link to post
Share on other sites

%asminclude is a bit broken at the moment, I now realize.

you could try %asmbinary?   if you prefix it with a label in the source code you should be able to refer to it from prog8

Share this post


Link to post
Share on other sites

I tried this

screen {

testlabel:
  %asmbinary "data.bin"
  ...
}

but get the following error :

screen.p8:3:9: no viable alternative at input 'testlabel:'

Share this post


Link to post
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)

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.

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.


×
×
  • Create New...

Important Information

Please review our Terms of Use