Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested enhancements #87

Open
studio8502 opened this issue Dec 10, 2020 · 4 comments
Open

Suggested enhancements #87

studio8502 opened this issue Dec 10, 2020 · 4 comments

Comments

@studio8502
Copy link

I'm liking what I'm learning of Millfork so far, but there are a couple things that I've wished it had.

  • It would be very nice to be able to define a struct that contained an array.
  • I'd love to have a predefined constant for every variable such that "foo.$bank" or some such would resolve to the value of the bank attribute of the segment in which "foo" is defined.
  • Computed variables; basically functions that set or get a value, but expressed syntactically as functions.
  • A per-bank output mode to go with the one-file and per-segment output modes, where I could define a bank size, and Millfork would just stick all the segments with that bank id into that bank's file.
  • Given that the 6502 supports BCD natively, the ability to tag an integer variable as being in BCD would be great.
  • It honestly bugs me that segment.NAME.start gives the address of the first used byte in the segment and not the value I defined in segment_NAME_start in the .ini file.
@KarolS
Copy link
Owner

KarolS commented Dec 10, 2020

  • It would be very nice to be able to define a struct that contained an array.

This is on the roadmap.

  • I'd love to have a predefined constant for every variable such that "foo.$bank" or some such would resolve to the value of the bank attribute of the segment in which "foo" is defined.

This is too. I'm now surprised that I forgot to implement it yet.

  • Computed variables; basically functions that set or get a value, but expressed syntactically as functions.

What is your use case and what would the benefits be over just having two normal functions?

Millfork in general tries to be transparent, like C or Java.

  • A per-bank output mode to go with the one-file and per-segment output modes, where I could define a bank size, and Millfork would just stick all the segments with that bank id into that bank's file.

Sound like a good idea. But what exactly do you mean, like if you have a segment $2000-$2FFF with bank id=1, another $3000-$3FFF also with bank id=1, and the output file contains $2000-$3FFF? This would require that the segments with the same bank id don't overlap, and there can be gaps between segments if the declared address range is too large. Is this what you meant?

  • Given that the 6502 supports BCD natively, the ability to tag an integer variable as being in BCD would be great.

Currently, there are separate operators, but I guess it's easy to forget which variable is should be treated as decimal and which as binary. I'll think about it.

I'm working on a feature I'm tentatively calling optimization hints, which will work like annotations in other languages. I guess that instead of polluting the type system with types like decimal2, annotating variables as either binary or decimal could do the trick.

  • It honestly bugs me that segment.NAME.start gives the address of the first used byte in the segment and not the value I defined in segment_NAME_start in the .ini file.

Agreed, that should be changed.

@studio8502
Copy link
Author

  • It would be very nice to be able to define a struct that contained an array.

This is on the roadmap.

Fantastic. It's not the biggest deal, certainly not a dealbreaker by any means, but in my particular use, for example in C64 tile maps, where a tile is an array of sixteen bytes and a tileset contains up to 256 tiles, you can imagine why I'd miss being able to express it that way.

  • I'd love to have a predefined constant for every variable such that "foo.$bank" or some such would resolve to the value of the bank attribute of the segment in which "foo" is defined.

This is too. I'm now surprised that I forgot to implement it yet.

If you never needed to use it, it's completely understandable that it slipped your mind. I only noticed its absence because I develop for a 512KB banked ROM cart on the C64.

  • Computed variables; basically functions that set or get a value, but expressed syntactically as functions.

What is your use case and what would the benefits be over just having two normal functions?

Convenience, mostly -- for example, on the C64, sprite position information for the X coordinate is split between the low byte and the highest bit, with the high bit in a shared byte -- it would be very convenient and make my code more readable if I could just say something like this:

unsigned16 sprite_0_x { get { // stuff in here to get the 16 bit unsigned value of sprite 0's x position } set { // stuff in here to set the byte and bit of sprite 0's x position } }

and then access it as if it were just another variable, with the compiler just translating it into calls to _sprite_0_x_get_u16() and _sprite_0_x_set_u16(newValue) or the like. It's not a must-have, just something I really, really liked in Swift that I think is an easy fit into most other languages.

Millfork in general tries to be transparent, like C or Java.

  • A per-bank output mode to go with the one-file and per-segment output modes, where I could define a bank size, and Millfork would just stick all the segments with that bank id into that bank's file.

Sound like a good idea. But what exactly do you mean, like if you have a segment $2000-$2FFF with bank id=1, another $3000-$3FFF also with bank id=1, and the output file contains $2000-$3FFF? This would require that the segments with the same bank id don't overlap, and there can be gaps between segments if the declared address range is too large. Is this what you meant?

I mean that, for example, if I assign segments prg2 and prg3 to bank 2, and they don't overlap, and their total length plus the gap between doesn't exceed the length I set as the bank length in the .ini file, then they would be spat out into the bank's output at the appropriate distance from one another, with the bank's fill value between them. It's just an extension of what Millfork already does inside each segment, brought up one conceptual level, to make organizing my segments in banks easier.

  • Given that the 6502 supports BCD natively, the ability to tag an integer variable as being in BCD would be great.

Currently, there are separate operators, but I guess it's easy to forget which variable is should be treated as decimal and which as binary. I'll think about it.

Good enough for me. Just something like bcd unsigned8 myVariable = 4 or bcd unsigned32 highScore0 = 1234 or the like.

I'm working on a feature I'm tentatively calling optimization hints, which will work like annotations in other languages. I guess that instead of polluting the type system with types like decimal2, annotating variables as either binary or decimal could do the trick.

  • It honestly bugs me that segment.NAME.start gives the address of the first used byte in the segment and not the value I defined in segment_NAME_start in the .ini file.

Agreed, that should be changed.

Awesome.

Thanks for taking feedback so well. I'm not the best at giving it, but it's nice to be heard.

@james7780
Copy link

+1 for adding the ability to put arrays in structs. For example in the Atari Lynx example code, the SCB struct should really have an array of 8 ubytes for the palette mapping values.

@studio8502
Copy link
Author

Holy crow, thank you! This is going to make my job so much easier with my game!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants