Jump to content
IGNORED

IntyBASIC compiler v1.0 wish list and 'contrib' dir


nanochess

Recommended Posts

 

I think that's what you're trying to get at. I think it's a valid idea to pursue in this context. Allow folks to declare Boolean state variables and provide primitives for setting them, clearing them and testing them. That is a common pattern in many games and could be very useful in an IntyBASIC context.

 

For those following along, here's a summary of the discussion so far:

  • CrazyBoss requested Boolean variables
  • Freeweed said they're a waste and that any game programmer worth his salt should not depend on such abstractions and should learn how to manage bitmaps with bitwise expressions.
  • I said it's more than a waste, it's a complex beast that can result in stupid or broken models, but maybe worth pursuing if done right; and that abstractions always have their place in higher-level languages.
  • Freeweed and intvnut insist that for a constrained platform like the Intellivision, it may not be worth it.
  • I concede that for a general implementation it may not be worth it, but insist that we're not talking about general all-purpose language features, but specific use cases to ease development of Intellivision games.
  • I then go into a philosophical soliloquy describing how abstractions are always better, and that implementation being "hard" is not the same as it being "impossible" or "worthless."
  • Intvnut agrees with the main point.

So, let's then rephrase the request:

 

Nanochess, I recommend you add support for "flag" variables that represent a true or false state, and offer Set and Clear statements to manipulate them. Not strictly boolean, they do not correspond to the logical truth that is the output of boolean expressions. These can grouped into bitmaps, and the compiler can generate optimized code for testing them.

 

-dZ.

  • Like 1
Link to comment
Share on other sites

For a nybble of bit flags this approach is pretty neat :-

 

http://atariage.com/forums/topic/169583-programming-tricks-better-bit-flags/

 

I remember when you posted that, that's a neat trick. I started using it in my game code.

 

However, I not only constrain myself to four bits; I use a full 16-bit word for the flags. I SWAP or SHIFT the register as necessary to align the rest. Plus, SWAPing and SHIFTing set the status flags as well, so it's like a bonus prior to using RSWD.

 

Of course, that's only an improvement if the flags are tested frequently and close together, which in my case they are. I then put the most common in their priority seat, pre-aligned with the RSWD flag bits.

 

-dZ.

  • Like 1
Link to comment
Share on other sites

  • Freeweed said they're a waste and that any game programmer worth his salt should not depend on such abstractions and should learn how to manage bitmaps with bitwise expressions.

 

To be clear, what I was originally implying is that any programmer writing for this platform who CAN'T do this level of bitmapping is screwed anyway, because they'll never be able to talk to the STIC. It's not a matter of being "worth your salt", it's just that doing practically anything with the STIC is an order of magnitude more difficult than setting/clearing/checking a single bit.

 

Where I was leading with that is that it would be nice to have a better abstraction for all of the various bits there. Tarzilla has a nice CONST scheme to help remember much of it, but I find that somewhat unwieldy. So far the best shortcut I've found is ((256+card_addr)*8+color, but there are still some magic numbers in there. And it's just plain inelegant.

Edited by freeweed
Link to comment
Share on other sites

To be clear, what I was originally implying is that any programmer writing for this platform who CAN'T do this level of bitmapping is screwed anyway, because they'll never be able to talk to the STIC. It's not a matter of being "worth your salt", it's just that doing practically anything with the STIC is an order of magnitude more difficult than setting/clearing/checking a single bit.

 

Where I was leading with that is that it would be nice to have a better abstraction for all of the various bits there. Tarzilla has a nice CONST scheme to help remember much of it, but I find that somewhat unwieldy. So far the best shortcut I've found is ((256+card_addr)*8+color, but there are still some magic numbers in there. And it's just plain inelegant.

 

What I tend to do is abstract the STIC itself. Then I can say:

    MOB.SetFlag(MOB1, Visible)
    MOB.SetZoom(MOB1, xDouble, yQuad)
    MOB.SetPosition(MOB1, 100, 50)
    MOB.SetVelocityX(MOB1, 100)
    MOB.SetVelocityY(MOB1, 0)

 

Not need to fiddle with bits while coding the game, let the framework (or the language) do the heavy lifting.

 

Perhaps IntyBASIC can do something like this?

 

-dZ.

  • Like 2
Link to comment
Share on other sites

 

I remember when you posted that, that's a neat trick. I started using it in my game code.

 

However, I not only constrain myself to four bits; I use a full 16-bit word for the flags. I SWAP or SHIFT the register as necessary to align the rest. Plus, SWAPing and SHIFTing set the status flags as well, so it's like a bonus prior to using RSWD.

 

Of course, that's only an improvement if the flags are tested frequently and close together, which in my case they are. I then put the most common in their priority seat, pre-aligned with the RSWD flag bits.

 

-dZ.

 

Yeah, you can end up testing all the bits in a few instructions. I think the following is correct.

     RSWD  R0      ; gives you bits 7, 6, 5, 4 in S, Z, OV, C
     BMI   @@bit7_set
     BEQ   @@bit6_set
     BOV   @@bit5_set
     BC    @@bit4_set
     SLLC  R0, 2   ; gives you bits 15 in C, 14 in OV, bit 13 in S
     BC    @@bit15_set
     BOV   @@bit14_set
     BMI   @@bit13_set
     SLLC  R0, 2   ; gives bit 13 in C (redundant), bit 12 in OV, bit, bit11 in S
     BOV   @@bit12_set
     BMI   @@bit11_set
     RSWD  R0      ; gives you bits 3, 2, 1, 0 in S, Z, OV, C
     BMI   @@bit3_set
     BEQ   @@bit2_set
     BOV   @@bit1_set
     BC    @@bit0_set
     SWAP  R0
     RSWD  R0      ; gives you bits 11, 10, 9, 8 in S, Z, OV, C.  Bit 11 is redundant
     BEQ   @@bit10_set
     BOV   @@bit9_set
     BC    @@bit8_set

Link to comment
Share on other sites

Got another suggestion; I don't even know if it's remotely possible:

 

For using the music player, DATA x controls the speed essentially. It would be very cool if x could be controlled by variable - ie: dynamically be able to speed up and slow down music within a game. Failing that (I took a brief gander at what it ends up as in ASM) - would it be possible to have the DATA line not so intricately connected to the following MUSIC DECLEs?

 

ie: something like PLAY my_song,5

 

Then later in the game PLAY my_song,6

 

But re-use the same music.

 

Right now the only way I can think to do this is to duplicate the MUSIC code. Yeah, ROM space is cheap, but still. Seems wasteful just for a one-character difference. Plus I'd like to be able to apply this to rather long selections of music :)

 

Btw, I'm sure I've said it before but: the music player is freaking awesome!

  • Like 1
Link to comment
Share on other sites

Here's another suggestion: Extensibility.

 

I don't know how practical it would be, but I can imagine ways to implement a "plug-in" architecture, where third-party programmers can create library files in Assembly Language, and have the procedures in the library "hook" to the language automatically to extend it via a defined interface.

 

For instance, suppose I want to implement the "ABS" function. In this architecture, there would be a standard register or memory location for the input and output values, and my function would adhere to that. When an IntyBASIC programmer "registers" this module in his program, he can now use "ABS" as part of arithmetic expressions and the compiler would process it accordingly.

 

This is more than just adding a subroutine to the program, since the "plug-in" architecture will ensure maximum efficiency by integrating the external function as a built-in language feature.

 

It's like old school TSRs used to patch BASIC in memory, except that now we can do so statically since we have a compiler. :)

 

-dZ.

  • Like 2
Link to comment
Share on other sites

That's a very cool idea, if it could be pulled off. Some things shouldn't be in the basic spec (and included needlessly in everyone's code) but it would be nice to have add-ons. The only thing I'm not sure of is if nanochess would have to arbitrate memory and register usage somehow, to avoid things clobbering each other.

Link to comment
Share on other sites

That's a very cool idea, if it could be pulled off. Some things shouldn't be in the basic spec (and included needlessly in everyone's code) but it would be nice to have add-ons. The only thing I'm not sure of is if nanochess would have to arbitrate memory and register usage somehow, to avoid things clobbering each other.

Well, nanochess could define specific constraints on registers, the stack, and memory, and it's on the plug-in programmer to follow them.

 

dZ.

Link to comment
Share on other sites

Well, nanochess could define specific constraints on registers, the stack, and memory, and it's on the plug-in programmer to follow them.

 

dZ.

 

Well, you're most of the way there with inline ASM. If you look at the IntyBASIC assembly output, it's really rather undemanding in terms of register usage. Registers get used within an expression, but don't seem to be reused between expressions.

 

A really simple hook mechanism might be this:

  • Allow declaring an "external procedure". Then GOSUB would go there, and you're cool. Right now, I think you have to do an "ASM CALL foo" instead. It's really syntactic sugar.
  • Allow declaring an "external function." Parameters show up in R0, R1, R2, R3, R4. (Max 5 parameters; R5 is return address, R6 is stack, R7 is program counter. Or, perhaps parameters above 5 go on the stack.) Result returned in R0. In IntyBASIC syntax, it would look like a typical BASIC function taking multiple values and returning a single value. ie. FUNC( a, b, c ). Think of it being like DEF USR. The function would need to save/restore R1 .. R4 if it uses them, though.

That's adequate if the functions/procedures don't need any RAM of their own. If you want to use some RAM, then that's a different issue. If IntyBASIC adopts cart.mac or P-Machinery code into its prolog/epilog and uses the corresponding facilities to allocate variables, then those same facilities will be available to assembly writers. Otherwise, to work well, IntyBASIC would need to leave some breadcrumbs around so that assembly code knows what locations are available and which ones aren't.

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

 

Well, you're most of the way there with inline ASM. If you look at the IntyBASIC assembly output, it's really rather undemanding in terms of register usage. Registers get used within an expression, but don't seem to be reused between expressions.

 

A really simple hook mechanism might be this:

  • Allow declaring an "external procedure". Then GOSUB would go there, and you're cool. Right now, I think you have to do an "ASM CALL foo" instead. It's really syntactic sugar.
  • Allow declaring an "external function." Parameters show up in R0, R1, R2, R3, R4. (Max 5 parameters; R5 is return address, R6 is stack, R7 is program counter. Or, perhaps parameters above 5 go on the stack.) Result returned in R0. In IntyBASIC syntax, it would look like a typical BASIC function taking multiple values and returning a single value. ie. FUNC( a, b, c ). Think of it being like DEF USR. The function would need to save/restore R1 .. R4 if it uses them, though.

That's adequate if the functions/procedures don't need any RAM of their own. If you want to use some RAM, then that's a different issue. If IntyBASIC adopts cart.mac or P-Machinery code into its prolog/epilog and uses the corresponding facilities to allocate variables, then those same facilities will be available to assembly writers. Otherwise, to work well, IntyBASIC would need to leave some breadcrumbs around so that assembly code knows what locations are available and which ones aren't.

 

That's what I'm talking about, except that I left the implementation details to nanochess. ;)

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.
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...