Brian's Man Cave Posted October 21, 2021 Share Posted October 21, 2021 I am trying to understand how to add more space as my game seems to be hitting a limit. I originally had put ASM ORG $B000 just after my game loop and it solved my problem. But now it seems to be happening again. I inserted ASM ORG $C100 several lines down and I no longer get the error when I try to compile the program, it runs but I get a bunch of GROM characters all over the place. Perhaps I am not understanding how this works? Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 21, 2021 Share Posted October 21, 2021 It sounds good to me. See contrib/42k.bas for which addresses the segments cover: REM SEGMENT ADDRESS RANGE SIZE NOTES REM ======= ============== ===== ===== REM 0 $5000 to $6FFF $2000 - Default segment REM 1 $A000 to $BFFF $2000 REM 2 $C040 to $FFFF $3FC0 - Avoid STIC aliasing. REM 3 $2100 to $2FFF $0F00 REM 4 $7100 to $7FFF $0F00 - Avoid EXEC's ECS ROM probe. REM 5 $4810 to $4FFF $0800 - Account for game's ECS ROM mapping out code. Do you have a block of graphics definitions that would cross two segments with an ASM ORG in the middle? I'm not sure if that would be the case, but just like I mentioned to Mik's Arcade, enable generation of list files if you already don't, and look through those for your labels to see which addresses those end up at. Quote Link to comment Share on other sites More sharing options...
Mik's Arcade Posted October 21, 2021 Share Posted October 21, 2021 (edited) funny, i literally just ran into this issue with my program yesterday. I don't know for a fact, but I would try taking out the ASM ORG $C100 and test moving the ASM ORG $B0000 down further in the code. I think you might have it in before the section actually runs out thus wasting some space. I could be wrong, but give it a try. Hopefully one of the gurus chimes in with a more intelligent reply. By the time I ran into this issue, it was occuring well after my main loop and down past most of my GOTO and SUBLOB logic so that is where I put my ASM. Of course your main loop might be bigger than mine.... EDIT: And now that Carlsson beat me to the punch, this DID occur to me after I added the DATA statements for a new screen I built using IntyColor. Now, all of my music, bitmaps and data statements are in the segment after the ASM statement....hopefully that is right...haha Edited October 21, 2021 by Mik's Arcade Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 21, 2021 Share Posted October 21, 2021 Personally I like to have the structure main code - subroutines - generic data - graphics definitions - screen cards - music but you can have it any order. Some like to interleave graphics with subroutines for a logic flow what belongs together. By checking the list file, you can also compute which sections are larger or smaller, which ones you could move up or down in order to optimize memory usage within a segment. Just avoid having a subroutine, a block of graphics etc overflow a segment or force an ORG statement in the middle of it. Move all of it to a new segment, perhaps rearrange something smaller to fit in its space. Quote Link to comment Share on other sites More sharing options...
Brian's Man Cave Posted October 21, 2021 Author Share Posted October 21, 2021 (edited) I know that Oscar once suggested to me that I check the list file, but I don't see that anywhere. All I can find is a .cfg and when I open it I see this: [mapping] $0000 - $0443 = $5000 $0444 - $1343 = $C100 $1344 - $2343 = $D000 $2344 - $3343 = $E000 $3344 - $3A40 = $F000 Edited October 21, 2021 by Brian's Man Cave Quote Link to comment Share on other sites More sharing options...
Zendocon Posted October 21, 2021 Share Posted October 21, 2021 (edited) 9 minutes ago, Brian's Man Cave said: I know that Oscar once suggested to me that I check the list file, but I don't see that anywhere. All I can find is a .cfg and when I open it I see this: [mapping] $0000 - $0443 = $5000 $0444 - $1343 = $C100 $1344 - $2343 = $D000 $2344 - $3343 = $E000 $3344 - $3A40 = $F000 Yes, keep an eye on the .cfg and know how to interpret it. In fact, I have my Make script display the contents of this file after successful assembly, so I can monitor the growth of the ROM image. Right away, I see what's up. You have a block that started at $C100 and went all the way into the $Fxxx range. Try to limit $F000 to graphics, lookup tables, and metadata. All my projects are broken up into multiple .bas files, and my main.bas is little more than a bunch of INCLUDE statements, as you can see on page 283 of the Advanced Game Programming book. What you want to do in your case is have a block of code use the 8K space available from $A000-BFFF, and the remainder use the space from $C100-DFFF (you can start at $C040 instead of $C100). I can help you further if need be. Edited October 21, 2021 by Zendocon Typo Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 21, 2021 Share Posted October 21, 2021 It seems like you're having ASM ORG quite early on, since you only use around 13% of the first segment. While utilizing 100% might be near impossible depending on how your program is structured, I think 85-90% should almost always be doable. I remembered that the list file is generated by as1600, not the compiler. Are you using the SDK? I think there is a build script that gives the -l parameter to the assembler. 1 Quote Link to comment Share on other sites More sharing options...
Brian's Man Cave Posted October 21, 2021 Author Share Posted October 21, 2021 Yes I am using the SDK Quote Link to comment Share on other sites More sharing options...
Brian's Man Cave Posted October 21, 2021 Author Share Posted October 21, 2021 Here is how my program is laid out: variables game loop bitmaps Screens Procedures Quote Link to comment Share on other sites More sharing options...
carlsson Posted October 21, 2021 Share Posted October 21, 2021 Try moving the procedures before bitmaps then, as Zendocon hinted about. What is variables, do you mean fixed game data that you load into variables? Or constants? Those don't take any space, but are in the correct position in that case. 1 Quote Link to comment Share on other sites More sharing options...
Zendocon Posted October 21, 2021 Share Posted October 21, 2021 Just now, Brian's Man Cave said: Here is how my program is laid out: variables game loop bitmaps Screens Procedures Good. I assume those are in separate files. That will make it easy to shuffle things around with a bunch of INCLUDE statements. Depending on how large those blocks are, your Bitmaps and Screens can probably safely go into $F000. Variables has no effect on the ROM size. Your Game Loop and Procedures might have to be broken up into multiple files, since your total ROM size is ~14.5K right now ($3A40 is the last virtual ROM address in your .cfg file). Quote Link to comment Share on other sites More sharing options...
Zendocon Posted October 21, 2021 Share Posted October 21, 2021 A couple more points: You'll know if you overflow past the end of $F000, because as1600 will suddenly throw a large number of errors. It wasn't mentioned in the original Game Programming book, but try to stay out of the $E000 range, because that will jeopardize ECS compatibility. LTO Flash can use a little bankswitching to work around that issue, if you flag your ROM as ECS incompatible (that's what I ended up doing for Blix & Chocolate Mine). 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 21, 2021 Share Posted October 21, 2021 (edited) 42 minutes ago, carlsson said: It seems like you're having ASM ORG quite early on, since you only use around 13% of the first segment. While utilizing 100% might be near impossible depending on how your program is structured, I think 85-90% should almost always be doable. I remembered that the list file is generated by as1600, not the compiler. Are you using the SDK? I think there is a build script that gives the -l parameter to the assembler. The SDK generates those files automatically when using the "INTYBUILD" tool. 41 minutes ago, Brian's Man Cave said: Yes I am using the SDK The next version of the SDK will include a ROM segment selector macro. If you want to use this right now, let me know, and I can send the the module that manages the segments, and a copy of the altered "prologue.bas" and "epilogue.bas" files. The macro is of the format: ;; ======================================================================== ;; ;; ROM.SwitchSeg seg ;; ;; Switches the program counter to a different ROM segment. It also closes ;; ;; the currently open segment. ;; ;; ;; ;; ARGUMENTS ;; ;; seg The ROM segment to open. ;; ;; ;; ;; OUTPUT ;; ;; _rom.error -1 on failure. ;; ;; ======================================================================== ;; MACRO ROM.SwitchSeg seg And it defines the following 6 segments, taken from the "CART.MAC" macro library from the SDK-1600. ; -------------------------------------- ; Memory map for 42K ROM cartridge ; -------------------------------------- ; SEGMENT RANGE ; 0 $5000 - $6FFF : 8K ; 1 $A000 - $BFFF : 8K ; 2 $C040 - $FFFF : 16K ; 3 $2100 - $2FFF : 4K ; 4 $7100 - $7FFF : 4K ; 5 $4800 - $4FFF : 2K ; ; CARTRAM $8040 - $9EFF : 8K ; -------------------------------------- The macro will form part of the SDK working environment, and default to ROM Segment #0 ($5000 - $6FFF), which is the default right now as well. To switch segments, all you need to do is invoke the macro like this: ' Switch to Segment #2 ASM ROM.SwitchSeg 2 If you know the size of the data or code you need, you could use the "ROM.AutoSeg" macro, which will pick the first segment available that has at least that capacity: ' Find a segment that can fit 2000 words ROM.AutoSeg 2000 It will also help you figure out how to allocate your segments by illustrating their current usage, like this: IntyBASIC SDK Compiler Build Script (intybuild) Created by: DZ-Jay Version: 1.2.3 Last updated: 10/09/2021 Compiling... Assembling... ROM USAGE: ======================================================= Segment Size Used Available ======================================================= ROM Seg #0 8K 629 7563 words ROM Seg #1 8K 2170 6022 words ROM Seg #2 16K 16315 5 words ROM Seg #3 4K 0 3840 words ROM Seg #4 4K 0 3840 words ROM Seg #5 2K 14 2034 words ======================================================= TOTAL: 42K 19128 23304 words ======================================================= ERROR SUMMARY - ERRORS DETECTED 0 - WARNINGS 0 When a segment overflows, you will obviously get an error and assemblage will fail, but the "Available" column will tell you which segment overflowed and by how much. For example: IntyBASIC SDK Compiler Build Script (intybuild) Created by: DZ-Jay Version: 1.2.3 Last updated: 10/09/2021 Compiling... Assembling... ROM USAGE: ======================================================= Segment Size Used Available ======================================================= ROM Seg #0 8K 16944 -8752 words ROM Seg #1 8K 2170 6022 words ROM Seg #2 16K 0 16320 words ROM Seg #3 4K 0 3840 words ROM Seg #4 4K 0 3840 words ROM Seg #5 2K 14 2034 words ======================================================= TOTAL: 42K 19128 23304 words ======================================================= ERROR SUMMARY - ERRORS DETECTED 1 - WARNINGS 0 ERROR: AS1600 assemblage failed. In the above example, I can see that Segment #0 has overflown by 8,752 words. I can then inspect my code to see which parts are in Segment #0 and split it further into other segments. This becomes a lot easier to do if you split your code into multiple modules, like for data or subroutines. Then you can do something like this: ' Include data modules ASM ROM.SwitchSeg 1 INCLUDE "sprites.bas" INCLUDE "music.bas" ASM ROM.SwitchSeg 2 INCLUDE "velocity.bas" ' Include subroutine modules ASM ROM.SwitchSeg 3 INCLUDE "collision-lib.bas" INCLUDE "input-lib.bas" Let me know if you wish to use this feature now, and I'll send you a PM with the details and instructions. -dZ. Edited October 21, 2021 by DZ-Jay 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 21, 2021 Share Posted October 21, 2021 (edited) 30 minutes ago, Zendocon said: A couple more points: You'll know if you overflow past the end of $F000, because as1600 will suddenly throw a large number of errors. It wasn't mentioned in the original Game Programming book, but try to stay out of the $E000 range, because that will jeopardize ECS compatibility. LTO Flash can use a little bankswitching to work around that issue, if you flag your ROM as ECS incompatible (that's what I ended up doing for Blix & Chocolate Mine). That's a good point. For ROMs that are going to be played on the emulator or on an LTO Flash, that's mostly a non-issue, since both JLP boards (like the LTO Flash) and the jzIntv emulator support bank-switching. For games to be distributed in non-JLP cartridges, this needs to be considered. -dZ. Edited October 21, 2021 by DZ-Jay 1 Quote Link to comment Share on other sites More sharing options...
Mik's Arcade Posted October 21, 2021 Share Posted October 21, 2021 (edited) this is a great topic and vey helpful to me as I just bumped up against this issue for the first time, too. This adds a lot more details on how to handle the issue. great stuff, thanks everyone for the tips and explanations. I would never be able to make a game without all the help I get here. I'm so dumb I cant even create a topic in the right subforum these days. Edited October 21, 2021 by Mik's Arcade Quote Link to comment Share on other sites More sharing options...
Brian's Man Cave Posted October 21, 2021 Author Share Posted October 21, 2021 I am trying this and its just putting out errors: ASM ORG $a000 include"rags_game_loop.bas" ASM ORG $c100 include"rags_procedures.bas" ASM ORG $F000 include"rags_streets.bas" Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 21, 2021 Share Posted October 21, 2021 1 minute ago, Brian's Man Cave said: I am trying this and its just putting out errors: ASM ORG $a000 include"rags_game_loop.bas" ASM ORG $c100 include"rags_procedures.bas" ASM ORG $F000 include"rags_streets.bas" Send me the SDK project and I'll take a look at it to see what's wrong. You can just ZIP up the entire project folder for your game. -dZ. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 21, 2021 Share Posted October 21, 2021 (edited) I took a peek at the source code and built it locally and ... Long story short: Two of the modules are over 8K, so only one can fit in the 16K segment at $C040, and there is no other contiguous block that can fit the other. I've recommended to split the data module into smaller modules, to keep them under 8K each and spread the load around. -dZ. Edited October 21, 2021 by DZ-Jay 1 Quote Link to comment Share on other sites More sharing options...
Zendocon Posted October 21, 2021 Share Posted October 21, 2021 33 minutes ago, Brian's Man Cave said: I am trying this and its just putting out errors: ASM ORG $a000 include"rags_game_loop.bas" ASM ORG $c100 include"rags_procedures.bas" ASM ORG $F000 include"rags_streets.bas" What are the errors? If IntyBASIC compiles with no errors but as1600 throws a bunch of errors with no explanation, then "rags_streets.bas" is probably overflowing past the end of $F000. Otherwise, everything looks fine so far. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted October 21, 2021 Share Posted October 21, 2021 (edited) Recommendations for the absolute novice. 1. Remove all the ASM ORG statements from your program. 2. Recompile your program (make sure it doesn't generate errors). 3. Read the generated LST file. (this file is generated by the assembler as1600). 4. Follow the address where each instruction is put (the 4 hexadecimal digits at the left). 5. Notice how each line of your original source code is alongside as comments. 6. All IntyBASIC programs start at $5000, when you find a cross over $7000 you need to insert the first ASM ORG statement (just before PROCEDURE or before a block of data). I would suggest ASM ORG $A000. 7. Recompile your program. 8. Read again the generated LST file. 9. Follow the address and watch how your program is assembled at $A000 at the point where you inserted ASM ORG $A000. 10. Check if something spills over $c000. At this point I would suggest ASM ORG $C100. Other segments available for use are $2100-$2fff (ASM ORG $2100) and $4810-$4fff (ASM ORG $4810). Symptons of crossing over $7000: The screen becomes purple and your game doesn't boot. (This is because the EXEC BIOS thinks there is a cartridge at $7000, it checks this first before checking $5000). Notice you need to check for as1600 total number of errors, because if you exceed $ffff then as1600 will throw an error for >each< assembler instruction exceeding the address space. Finally, you need to verify each time that you don't have exceeded these segments, but you don't need to read each time your whole program. This is as easy as listing the .CFG file (also generated by the assembler). Edited October 21, 2021 by nanochess 3 Quote Link to comment Share on other sites More sharing options...
Mik's Arcade Posted October 21, 2021 Share Posted October 21, 2021 Symptons of crossing over $7000: The screen becomes purple and your game doesn't boot. (This is because the EXEC BIOS thinks there is a cartridge at $7000, it checks this first before checking $5000). this is what happened to me 2 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 22, 2021 Share Posted October 22, 2021 (edited) 13 hours ago, nanochess said: Recommendations for the absolute novice. 1. Remove all the ASM ORG statements from your program. 2. Recompile your program (make sure it doesn't generate errors). 3. Read the generated LST file. (this file is generated by the assembler as1600). 4. Follow the address where each instruction is put (the 4 hexadecimal digits at the left). 5. Notice how each line of your original source code is alongside as comments. 6. All IntyBASIC programs start at $5000, when you find a cross over $7000 you need to insert the first ASM ORG statement (just before PROCEDURE or before a block of data). I would suggest ASM ORG $A000. 7. Recompile your program. 8. Read again the generated LST file. 9. Follow the address and watch how your program is assembled at $A000 at the point where you inserted ASM ORG $A000. 10. Check if something spills over $c000. At this point I would suggest ASM ORG $C100. Other segments available for use are $2100-$2fff (ASM ORG $2100) and $4810-$4fff (ASM ORG $4810). Symptons of crossing over $7000: The screen becomes purple and your game doesn't boot. (This is because the EXEC BIOS thinks there is a cartridge at $7000, it checks this first before checking $5000). Notice you need to check for as1600 total number of errors, because if you exceed $ffff then as1600 will throw an error for >each< assembler instruction exceeding the address space. Finally, you need to verify each time that you don't have exceeded these segments, but you don't need to read each time your whole program. This is as easy as listing the .CFG file (also generated by the assembler). I think this is really too complicated. I'm sure people can figure it out, but they have bigger fish to fry, what with getting up to speed with IntyBASIC and learning the ropes of making a video game -- there has to be a better way. I think a post-processing step (like intySmap, but after assemblage) could help to analyze errors in the assembly listing file and try to provide details related to ROM overruns. As you've suggested, all the information is there, and those are machine-readable files, so it should be possible to help the absolute novice a bit more. I'll try to get something done for the next version of the SDK, but there are much smarter people than me in this forum. The "ROM Segment" feature I added to the SDK is one possible solution, but it forces people into using a specific memory map, which may or may not be desirable. It also requires small changes to the epilogue and prologue to incorporate it. In the absence of a linker, I'm sure something that makes ROM segment overflow more clear and guides programmers on how to allocate their code, would be of great help to many. -dZ. Edited October 22, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
+cmadruga Posted October 27, 2021 Share Posted October 27, 2021 Please keep us bank switching aficionados in mind Managing segments AND pages simultaneously feels like solving a jigsaw at times. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted October 27, 2021 Share Posted October 27, 2021 (edited) 49 minutes ago, cmadruga said: Please keep us bank switching aficionados in mind Managing segments AND pages simultaneously feels like solving a jigsaw at times. The solution I'm planning to implement for the IntyBASIC SDK would give the choice of different memory maps that support or not JLP with bank-switching. For the memory maps that support bank-switching, one option could be to support "dynamic segments," in which instead of just selecting a ROM segment, you select a ROM segment and a page (from 0 to 15). My idea is to give a simple, no-frills option to those starting, without encumbering them with any further complications of banks and switching; while also giving options to those who want or need that power. The ultimate "no-frills" option would be to let the programmer do his or her thing without intervention (Pure! Ultimate! Powah!), and providing a post-build tool that provides information based on the output LISTING file that can alert to issues and guide decisions to address them. The SDK already runs IntySMap as part of its build process, so such a ROM-check tool can be added afterwards. I'll see if I can come up with something for this ROM-check tool, but it would be ideal if someone with better skills than me would take this on. I don't have any programming tools around to build Windows/Mac/Linux programs, and even if I did, it's been at least a decade since the last time I used anything other Perl, Python, or as1600. This is why the SDK uses Perl scripts (Mac) or COMMAND.COM batch scripts (Windows). -dZ. Edited October 27, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
+cmadruga Posted October 27, 2021 Share Posted October 27, 2021 It all sounds wonderful! 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.