erichenneke Posted February 25, 2016 Share Posted February 25, 2016 I have been working on a project and it is nearing completion. One thing I don't like is that I am still using the stock character set throughout the program (for text prompts, status, scoring, etc.). Unfortunately, i don't have much memory left at this point. I haven't ever redefined character sets, so I am not sure what my best options are. My question is, what is my best approach to redefine the characters I use in the program while using the very least memory possible? And realistically, how much memory is this going to eat up at a minimum? The program uses 101 unique characters in total: 49 of them are inverse 52 of them are regular ( non-inverse ) Graphics modes used are 2(with text window) and 7 (with text window). Thanks! Quote Link to comment Share on other sites More sharing options...
billkendrick Posted February 25, 2016 Share Posted February 25, 2016 If you're using fewer than 64 characters (e.g., CHR$(32), space, through CHR$(95), underscore), you can use just 512 bytes (1/2 KB). GRAPHICS 2 only lets you use 64 characters (with the top 2 bits controlling which of the four colors they appear in; so no inverse-video, lowercase, or [Control] or [Esc]-sequence graphics symbols). Of course, since you've got a text window, you'll need to avoid using any of the other 64 characters (CHR$ 0 thru 31, and 96 thru 127), since if you've not defined them, they'll appear as whatever 'garbage' pixels happen to be there (the rest of your program, for example). Inverse video of the allowed characters (so, CHR$ 160 thru 223) are fine, though. Basically, if you restrict yourself to always using just the characters visible in the GRAPHICS 2 text area, even within the GRAPHICS 0-style text window at the bottom, you'll be fine, and can just use a 512-byte font. Clear as mud? -bill! Quote Link to comment Share on other sites More sharing options...
erichenneke Posted February 25, 2016 Author Share Posted February 25, 2016 I only have about 600 bytes to work with, so that might work. Currently, these are exactly the characters being used... Regular(not inversed): ABCDEGHIKLMNOPRSTUVY!01234567890abcdefghilmnoprstuwy Inversed: ACDEFGIKLMNOPRSTUV!:0123456789acdefghilmnoprstuwy I'd prefer to keep the mix of upper and lower case letters if possible. Is it possibly with such a constricted amount of memory remaining to work with? If not, I guess I could go with all upper case if it would allow me to use an alternative font. Quote Link to comment Share on other sites More sharing options...
billkendrick Posted February 25, 2016 Share Posted February 25, 2016 Well, you can use whatever 64 symbols you want, but they'll have to be within characters 32-95 in your font (that is, starting at byte 0, up to byte 511, of the font data itself). So in other words, you'd have to map things from 'what you want to see' (e.g., lowercase "a") to 'which character in the font has that symbol'. For example, your font could have the symbols you want, in this order within the font: !abcdefghilmnop0123456789:rstuwyABCDE GHI KLMNOP RSTUVY Then you'd just map them to the ATASCII character you need to draw on the screen to get the font symbol/shape you want. In the case of the numbers, uppercase letters, colon, and exclamation point, I happened to put them in the same place. I fit the lowercase letters where there was leftover room, which meant they got split up: ATASCII: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWYZ[\]^_ Font: !abcdefghilmnop0123456789:rstuwyABCDE GHI KLMNOP RSTUVY You don't need to do it that way. You can just shove them all in whatever order best suits you, since you need to map things anyway. (i.e., in this case, you have to convert "lowercase 'a'" to the "double-quote (")" ATASCII character, when you draw it on the screen) e.g., you could do: !:0123456789ABCDEGHIKLMNOPRSTUVYabcdefghilmnoprstuwy or: !:0123456789AaBbCcDdEefGgHhIiKLlMmNnOoPpRrSsTtUuVwYy Whatever suits you! Now, that said -- you've mentioned inverse characters. You can use them just fine in the GRAPHICS 0-style text window (at the bottom of the GRAPHICS 2 & 7 screens). If you need symbols which appear inverse-video in the GRAPHICS 2 screen itself, you have to create symbols for them in your font. And unfortunately, you have too many symbols. (You can only show 64 unique symbols, in 4 different foreground colors; but you need 101 of them) In that case, you'll need to use GRAPHICS 7 mode all the time, and render the characters within the bitmap playfield. That'll be slow, but it'll be very easy to render symbols from your 512-byte font in inverse-video. (Just flip all the bits) Doing that has another advantage: normally your font needs to be on a page boundary (evenly divisible by 256) for ANTIC to use it. But if you're just rendering pixels manually, that restriction goes away. (Assuming you use the internal OS ROM font for the GRAPHICS 0-style text window.) Quote Link to comment Share on other sites More sharing options...
snicklin Posted February 26, 2016 Share Posted February 26, 2016 This may not be the most useful answer and sorry in advance if this is the case, but this is how I'd look into this. Question is, do you just want to get this out of the door or do you want neater code that is maintainable and useful in the future? If the first answer, ignore what I have to say. If the 2nd answer, carry on. Can you find a way to either compress some of the other data in your program or load it in as required from disk? The problem is that you're missing out the 'j' character as you don't use it, but you're going to have loads of hassle re-mapping your strings all for the sake of 8 bytes. And if you want to change your text to include a 'j', you'll have problems. Which language are you using? I have the feeling that you're using BASIC. Have you seen this? : http://www.atarimagazines.com/v9n2/basicspeedups.html If using an assembler, is optimisation switched on? Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 27, 2016 Share Posted February 27, 2016 For your needs it's likely a DLI might be required to change character set pointer onscreen. The memory requirement there isn't all that much but the problem becomes that you then have to segregate the 2 character sets such that any characters required on the same text row are defined in the same charset. It might come to the point where you end up needing duplicates. You'd probably do well to look for optimisations that can be had elsewhere. If you're using bitmap mode as well then you might be able to trim that window size down a bit. If you define your own DList then you can have a shortened bitmap area. Then it just takes a bit of trickery in telling the OS the origin of the screen and care in not trying to draw to areas that don't exist. Another alternative is to use character mode instead of bitmap but then you have the limitation on how much detail you can reproduce thanks to only 128 characters definable. The other option worth looking at is to use memory under Basic and the OS. Though that automatically means XL/later only for your program. Quote Link to comment Share on other sites More sharing options...
pirx Posted February 29, 2016 Share Posted February 29, 2016 If this is XL/XE software and you are not using RAM under ROM you can copy ROM to RAM below and modify charsets in its original space. 0 bytes taken this way. Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 29, 2016 Share Posted February 29, 2016 (edited) What should be asked is what language? A weakness of Basic and many other high-level ones - you can get a case where assembly language and graphics data has multiple copies resident. The common way is to have stuff in DATA statements which is very wasteful. 1 byte per Ascii character plus 1 per comma so 2 to 4 bytes for each byte you're representing, then you have the target so it becomes 3 to 5 times the actual usage. A more efficient method can be to use strings though they're not quite as easy to handle and not as easy to represent all byte values as 155 is reserved for RETURN and 34 for quote mark, and the comma becomes another problem if you read them from data. The thing there is you're still keeping 2 copies. For short relocatable assembly routines you can keep just one copy, then execute directly by USR(ADR(ST$)) Probably the best method in Basic is to include such data in external files then have a routine which reads direct to the required area. To speed up subsequent runs, you can just check a few values at start, middle, end to see if the data has already been loaded, and skip if it has. Edited February 29, 2016 by Rybags Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted February 29, 2016 Share Posted February 29, 2016 (edited) I used to put ML in a string thus: ROUTINE=ADR("<raw machine code>") If there were quotes or EOLs, I'd poke them to ROUTINE+OFFSET before calling. Only one copy of the data and worked well for 100-odd byte routines. Edit: I guess Gary already inferred this method now I read again. Edited February 29, 2016 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted February 29, 2016 Share Posted February 29, 2016 You can also keep the data in a different file. Such as a binary segment appended to your main file to pre-load areas of memory with data. In BASIC, it can go something like this: 10 gosub 1000:rem init routine 20 .. 30 .. Main code here 40 .. .. .. 999 end 1000 Enter "D:SETVARS.LST" ------------------------------------------ SETVARS.LST (made with text editor using NO line numbers) DIM SIO$(4) SIO$="hLVd" RETURN Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 2, 2016 Author Share Posted March 2, 2016 Ok, thank you all for the suggestions so far. You really got me thinking now about the possibilities. Like I said, I have never done any character set redefinition so this is all great for me to think through. Let met provide some more specifics to answer your questions. I hope we can nail this thing!: Language: Main loop logic: Compiled Turbo Basic XL DLI/VBI, PM and collision detection: Done in assembly (MADS compiler) (the machine code is loaded from a separate binary file before the compiled TBXL program executes) XL/XE compatible only? I am assuming since I am using compiled TBXL that I have already crossed that bridge a long time ago. Right? So 400/800 compatibility is probably not an option anyway. What am I trying to do with the character set redefinition? I am only using it for "more interesting looking text". It will NOT be used for graphics or anything like that, only so all the text prompts, scoring, status, etc will not be the boring stock font. That's it ! So here is what I am thinking I should pursue based on your ideas so far: 1) Place all of the character set definition data in a separate binary file to be loaded into memory before my compiled TBXL program executes 2) Load the character set definition data into the RAM space under the OS Am I on the right path? Also, I'll need help to implement that. If I load the character set data into the RAM under OS, won't I need to redirect some kind of pointers to know it should be using the data I place there instead of the stock font definitions? Again, for whatever reason, I've just never actually done any character set redefinition so in that regard I am a newbie. Really hungry to learn about it though. And this provides a good opportunity to tie it in (as compactly as possible ) for my current project. Really appreciate the continued suggestions and guidance! Thanks! Any illustrative code examples would be extremely helpful too. Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 2, 2016 Author Share Posted March 2, 2016 You can also keep the data in a different file. Such as a binary segment appended to your main file to pre-load areas of memory with data. In BASIC, it can go something like this: 10 gosub 1000:rem init routine 20 .. 30 .. Main code here 40 .. .. .. 999 end 1000 Enter "D:SETVARS.LST" ------------------------------------------ SETVARS.LST (made with text editor using NO line numbers) DIM SIO$(4) SIO$="hLVd" RETURN that's a really cool trick, never thought about using "ENTER" inline during program execution like that. I assume that won't work in a compiled TBXL program though. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted March 2, 2016 Share Posted March 2, 2016 (edited) that's a really cool trick, never thought about using "ENTER" inline during program execution like that. I assume that won't work in a compiled TBXL program though. No, I'm afraid not. Edit: It doesn't work in TB at all. Atari BASIC it works. Edited March 2, 2016 by Kyle22 Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 6, 2016 Author Share Posted March 6, 2016 Hey, since i am using compiled TBXL + assembly, do you see any reason I can't locate my character set definition data at $A800-$AC00 ?? Seems to work just fine but wanted to know if you see any pitfalls with that approach. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted March 6, 2016 Share Posted March 6, 2016 That area seems to be free. You could put your font in a separate file and use: open#1,4,0,"D:font.fnt" bget#1,$A800,$400 cl.#1 Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 7, 2016 Author Share Posted March 7, 2016 thanks. Yep, that's what i am doing. Actually i am just putting it in a separate binary file and loading it in at $A800. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.