Jump to content
petit chou

Lots of technical questions about the ORG directive and memory

Recommended Posts

Hey everybody,

 

I apologize if anyone has asked these question before -- I tried searching with limited success.

 

I am working on writing a roguelike for the INTV, now using IntyBASIC ideally to be part of the contest. The problem is that the program I want to write, including its art assets, is kind of huge and unwieldy and I have genuine worries that I'm not going to be able to cram everything I'd like into the address space.

 

The IntyBASIC manual has this to say about the subject:

 

 

Using modern Flash cart and homebrew cartridge PCBs allows following addresses to be used without additional programming:

$2000-$2FFF
$5000-$6FFF
$A000-$BFFF
$C100-$FFFF

 

The memory_map.txt file in the SDK, however, has what appears to be a much larger selection of addresses:

 

 

$0400 - $04FF RAM/ROM ok on all but Intellivision 2.

$0500 - $06FF RAM/ROM ok.
$0700 - $0CFF RAM/ROM ok if no Intellivoice.
$0D00 - $0FFF RAM/ROM ok.
$2000 - $2FFF RAM/ROM ok if no ECS.
$4000 - $47FF RAM/ROM ok if no ECS.
$4800 ROM ok. RAM ok only if boot ROM at $7000.
$4801 - $4FFF RAM/ROM ok.
$5000 - $5014 ROM ok. RAM ok only if boot ROM at $7000 or $4800.
$5015 - $6FFF RAM/ROM ok.
$7000 ROM ok if no ECS. RAM at $7000 confuses EXEC boot sequence.
$7001 - $77FF RAM/ROM ok if no ECS.
$7800 - $7FFF ROM ok if no ECS. Do not map RAM here due to GRAM alias.
$8000 - $8FFF RAM/ROM ok. Avoid STIC alias at $8000 - $803F.
$9000 - $B7FF RAM/ROM ok.
$B800 - $BFFF ROM ok. Do not map RAM here due to GRAM alias.
$C000 - $CFFF RAM/ROM ok. Avoid STIC alias at $C000 - $C03F.
$D000 - $DFFF RAM/ROM ok.
$E000 - $EFFF RAM/ROM ok if no ECS.
$F000 - $F7FF RAM/ROM ok.
$F800 - $FFFF ROM ok. Do not map RAM here due to GRAM alias.

 

So, the questions I have:

 

Does IntyBASIC attach to the areas listed in the memory map but not listed in its documentation ($4000-$4FFF, $7000-$7FFF, $8040-$9FFF) in order to store variables? What about its prologue/epilogue routines? Clearly those routines have to go somewhere, but I'm a little confused about what determines where they show up. The prologue looks like it starts at $5000 and it looks like the epilogue is using some of the address space in the $4000 block to store some routines, but is there any extra space that can be squeezed out of these areas?

 

There is no ORG directive at the beginning of the epilogue. Do those routines just go wherever the compiler's location counter happens to be pointing when it goes to include this? Will I need to worry about the epilogue writing itself to bizarre or inappropriate places if my code stops near one of the memory boundaries, or will the BASIC compiler make sure that doesn't happen?

 

Where is the entry point for IntyBASIC programs? I'd like to make a custom title screen if possible. If I start my program with ASM ORG $7000, will it begin execution there and bypass the EXEC? (Does IntyBASIC need the EXEC?) I noticed that there's some code at $4800 in the epilogue pertaining to the Intellivoice, but it looks like it may not be present if the Intellivoice isn't used.

 

(I realize half the reason for using BASIC instead of assembly language is to not have to worry about fiddly details like this, but I want to make good, appropriate decisions about how to organize my program and figure out what all I will be able to include as far as assets go before I begin any major coding.)

 

Thanks a bunch!

Share this post


Link to post
Share on other sites

Hey everybody,

 

I apologize if anyone has asked these question before -- I tried searching with limited success.

 

No worries, that's why we're here for. :)

 

I am working on writing a roguelike for the INTV, now using IntyBASIC ideally to be part of the contest. The problem is that the program I want to write, including its art assets, is kind of huge and unwieldy and I have genuine worries that I'm not going to be able to cram everything I'd like into the address space.

 

How big is "kind of huge and unwieldy"? Keep one thing in mind, the address space you quote is mostly composed of 16-bit segments, and in the Intellivision, when people speak of "K," they mean "Kilo Decles" not "Kilo Bytes" (a "Decle" being the common term for a 16-bit word -- well, actually for a 10-bit word, which is what the original designers used back when 16-bit ROMs were too expensive, but I digress).

 

That means that 8K means about 8 thousand 16-bit words, or 16KB. This may or may not have any bearing on your concerns, though.

 

Does IntyBASIC attach to the areas listed in the memory map but not listed in its documentation ($4000-$4FFF, $7000-$7FFF, $8040-$9FFF) in order to store variables? What about its prologue/epilogue routines? Clearly those routines have to go somewhere, but I'm a little confused about what determines where they show up. The prologue looks like it starts at $5000 and it looks like the epilogue is using some of the address space in the $4000 block to store some routines, but is there any extra space that can be squeezed out of these areas?

 

I believe IntyBASIC uses the "standard" 16K map defined in the SDK-1600:

                ; --------------------------------------
                ; Memory map for 16K ROM cartridge
                ; --------------------------------------
                ;   SEGMENT        RANGE
                ;      0           $5000 - $6FFF :  8K
                ;      1           $D000 - $DFFF :  4K
                ;      2           $F000 - $FFFF :  4K
                ;
                ;      8-bit RAM   $0100 - $01EF
                ;      16-bit RAM  $02F0 - $035F
                ; --------------------------------------

That's not counting the Background Table (BACKTAB) or the various devices (STIC, PSG, etc.).

 

Of that, it only uses the first segment, which means that the entire game program is expected to exist within the 8K from $5000 to $6FFF. (That's "8 K Decles," by the way. You see how it creeps up on you? ;))

 

 

There is no ORG directive at the beginning of the epilogue. Do those routines just go wherever the compiler's location counter happens to be pointing when it goes to include this? Will I need to worry about the epilogue writing itself to bizarre or inappropriate places if my code stops near one of the memory boundaries, or will the BASIC compiler make sure that doesn't happen?

 

 

The prologue assembles at the top of that address, at $5000, which is a rather standard expected place for cartridge ROM to exist, and grows from there. It grows to encompass your game code and data, and finally the epilogue. So yes, the prologue and epilogue routines just go wherever the assembler's program counter happens to be pointing at the time.

 

I'd say that, as you make your program, you will not have to worry about the epilogue or your code "writing itself to bizarre or inappropriate places," since those 8K are rather lofty and expansive. However, eventually, you may breach the memory boundary.

 

At that point, the IntyBASIC compiler will give you an error, but will not move the code for you.

 

That's what that hint in the manual about "ORG" is about: if you indeed breach the segment's upper boundary, then you'll have to figure out where is an appropriate breaking point in your code, and "ORG" a piece of it into a different segment. Perhaps one of those mentioned in the manual.

 

Yes, this is a very limiting behaviour, and one that Oscar has said he'll try to address someday. However, it's not a trivial problem to solve. Keep in mind that IntyBASIC only compiles into Assembly Language, so it defers all memory manipulation and boundaries and all that stuff to the assembler, which is completely out of its reach.

In the meantime, them's the breaks. :sad:

 

Where is the entry point for IntyBASIC programs? I'd like to make a custom title screen if possible. If I start my program with ASM ORG $7000, will it begin execution there and bypass the EXEC? (Does IntyBASIC need the EXEC?) I noticed that there's some code at $4800 in the epilogue pertaining to the Intellivoice, but it looks like it may not be present if the Intellivoice isn't used.

 

IntyBASIC only uses the EXEC inasmuch as any other Intellivision program requires it: as a platform to launch itself. The EXEC boots up the machine and sets itself up during start-up, and at some point during this phase it asks the program for some information and -- BAM!!! -- the program takes over and jumps on its own from there and never, ever, ever, looks back, thankyerverymuch! :cool:

 

Then there's the VBLANK interrupt that occurs every 60th of a second, in which the CPU control flow is interrupted, system state is saved in the stack, and control is diverted to the EXEC for the execution of an Interrupt Service Routine (ISR). Except that IntyBASIC has re-written the interrupt vector with its own address and has taken over once again!! BWAAHAHAHAHAHA!

 

Other than that, the EXEC is dead to IntyBASIC, unknown and forgotten, and ne'er the twain shall meet. (Well, your program may want to "return" to the EXEC interrupt branch for it to restore the system state and return control to the CPU where it left off. But even that is not strictly necessary if you want to do that yourself -- or forgo it completely! :o)

 

So, to make a custom title screen, all you have to do is write your routine right at the top of your BASIC program, as the very first thing. You recall when I said that the EXEC startup sequence asks the program for something and the program takes over? Well, what it actually does is that after the EXEC draws the title screen, it asks the program "Do you need anything else here, perhaps to fix the copyright year?" At that point (which is the beginning of your program) all you have to do is redraw the screen and wait for input. Oh yeah, and go on your merry program way and never return to the EXEC.

 

That's it. No need to muck about with ORGs and memory maps.

 

(I realize half the reason for using BASIC instead of assembly language is to not have to worry about fiddly details like this, but I want to make good, appropriate decisions about how to organize my program and figure out what all I will be able to include as far as assets go before I begin any major coding.)

 

Your questions are very reasonable and prudent. It is true that most of our answers will be "dude, don't worry too much about it"; but the fact remains that if you have enough understanding of the underlying system and how it works, you'll be better equipped to make decisions.

 

But really, dude, don't worry too much about it. Have fun and let's deal with the memory allocations if or when you breach that boundary. :)

 

-dZ.

Edited by DZ-Jay

Share this post


Link to post
Share on other sites

You usually don't need to worry about code locations used in your program. You can simply check the generated .CFG file (as1600 creates it) and see what locations is using your program.

 

The basic addresses are $5000-$6fff, $d000-$dfff and $f000-$ffff, these doesn't require any special coding except ASM ORG.

 

Using the other addresses suggested in my manual require a special mapper routine at $4800-$48ff (you can trigger it using SOUND 5-9, later I'll add a sample routine to manual), specially because it allows a large chunk starting at $c100 up to $ffff.

 

Every Intellivision game including IntyBASIC starts at $5000, checking the CFG file you can see if your program exceeds the allowed zones and insert ASM ORG in strategic points.

 

Usually for bigger Intellivision games I suggest to put DATA and BITMAP at the end of the game because these "move" less so these stay almost fixed in the address you've assigned.

 

Also some organization with PROCEDURE/END allows you to check the LST file and see where are being put each procedure and insert ASM ORG.

 

I know it's kind of awkward but gives you full control of where ends everything and allows you to use the full memory map for creating very big games ;)

  • Like 1

Share this post


Link to post
Share on other sites

Thank you both so very much for your informative (and encouraging!) replies. I'm excited to get to work on this!

  • Like 1

Share this post


Link to post
Share on other sites

If you are worried about level maps taking up too much space we can probably work out ways to compress/decompress them so they take up less space.

  • Like 1

Share this post


Link to post
Share on other sites

Also, it is possible to use page flipping from IntyBASIC. So, if you have many independent levels that don't share data, it is possible to store these in a way where you might only have one couple levels visible at a time, but you can switch between them easily. With page flipping you can go really huge.

 

I'll see if I can whip up a quick demo.

Share this post


Link to post
Share on other sites

Fellow newbie answer: I just wait until my program is so big that it no longer runs. Then I insert ORG statements in semi-random places, and move them around as needed. It's worked for me so far (biggest game is 56.6KB and growing). You eventually get a feel for where it makes sense to insert them. I've been working off a memory map provided by our good friend intvnut, which allows you 49K words (98KB). You can see that it gives 2 very large cunks and several smaller ones:

 

$2100 - $2FFF ; 4K words, minus 256 words
$4800 - $4FFF ; 2K words
$5000 - $6FFF ; 8K words
$7100 - $7FFF ; 4K words, minus 256 words
$8100 - $BFFF ; 16K words, minus 256 words
$C100 - $FFFF ; 16K words, minus 256 words

 

He did add a disclaimer to this though:

 

To make this work seamlessly with the ECS, you do need to add some code to either intybasic_prologue.asm or intybasic_epilogue.asm to add code at $4800 to switch out the ECS ROMs and (if the board you're using supports page flipping) switch in yours.

 

This code does not exist in IntyBASIC; you'd have to insert more ASM into your program. Which violates the contest rules. The ECS addresses in question are $E000-$EFFF (and a smattering of others?), so you could just avoid these and give up ~4K words, if you wanted to be 100% sure. This is still a LOT of game data. All with just a handful of ORG statements. The belief at the time was that we could probably get away with using those addresses anyway, but... "just in case". And of course, if you ever wanted to actually use the ECS, which IntyBASIC has limited support for now.

 

This info exists in a post on AA, but I'm too lazy to search. I keep this as my cheat sheet :D

 

Incidentally, the 56.6KB is jam-packed with level data (among other data). 3 maps of 64 screens that are tile-addressable from a choice of 16 options. That is a hell of a lot of screens and it's not just the same 4 repeating components. Take that Maze-a-Tron!

  • Like 1

Share this post


Link to post
Share on other sites

Here's a simple if crappy page flipping demo in IntyBASIC. In this example, LEVEL indicates a level number 0..5. The code assumes two LEVELs can fit on a page, and that you'll be reading level data via READ.

 

More sophisticated approaches are definitely possible.

 

Still, this demo does demonstrate it's possible to use page flipping from IntyBASIC.

 

One sad aspect: There is a bug in older versions of jzIntv that prevents it from page flipping page-flipped segments that are a size other than 4K correctly. This code includes an ASM macro that works around it. This macro isn't required by IntyBASIC or AS1600, but rather to work around a bug in jzIntv. It's fixed in the latest development build (and in the version on the jzIntv website), but not in 1.0-beta4.

 

 

page.zip

Share this post


Link to post
Share on other sites

Fellow newbie answer: I just wait until my program is so big that it no longer runs. Then I insert ORG statements in semi-random places, and move them around as needed. It's worked for me so far (biggest game is 56.6KB and growing). You eventually get a feel for where it makes sense to insert them. I've been working off a memory map provided by our good friend intvnut, which allows you 49K words (98KB). You can see that it gives 2 very large cunks and several smaller ones:

 

$2100 - $2FFF ; 4K words, minus 256 words

$4800 - $4FFF ; 2K words

$5000 - $6FFF ; 8K words

$7100 - $7FFF ; 4K words, minus 256 words

$8100 - $BFFF ; 16K words, minus 256 words

$C100 - $FFFF ; 16K words, minus 256 words

 

He did add a disclaimer to this though:

 

To make this work seamlessly with the ECS, you do need to add some code to either intybasic_prologue.asm or intybasic_epilogue.asm to add code at $4800 to switch out the ECS ROMs and (if the board you're using supports page flipping) switch in yours.

 

This code does not exist in IntyBASIC; you'd have to insert more ASM into your program. Which violates the contest rules. The ECS addresses in question are $E000-$EFFF (and a smattering of others?), so you could just avoid these and give up ~4K words, if you wanted to be 100% sure. This is still a LOT of game data. All with just a handful of ORG statements. The belief at the time was that we could probably get away with using those addresses anyway, but... "just in case". And of course, if you ever wanted to actually use the ECS, which IntyBASIC has limited support for now.

 

This info exists in a post on AA, but I'm too lazy to search. I keep this as my cheat sheet :D

 

Incidentally, the 56.6KB is jam-packed with level data (among other data). 3 maps of 64 screens that are tile-addressable from a choice of 16 options. That is a hell of a lot of screens and it's not just the same 4 repeating components. Take that Maze-a-Tron!

 

Once your code starts not fitting, I've worked out how you can page-flip. See my previous post for the skeleton of the idea in a simple proof-of-concept .BAS. :D

Share this post


Link to post
Share on other sites

 

Once your code starts not fitting, I've worked out how you can page-flip. See my previous post for the skeleton of the idea in a simple proof-of-concept .BAS. :D

 

My problem is that the data isn't in "levels" per se. I'd have to page-flip regions of a world, and somehow have the boundary areas still be consistent.

 

But damn, does that give me ideas for something else. Do we even have a limit on ROM size anymore? (Starts thinking about how any Turing-complete machine can do literally anything given infinite storage....)

Share this post


Link to post
Share on other sites

 

My problem is that the data isn't in "levels" per se. I'd have to page-flip regions of a world, and somehow have the boundary areas still be consistent.

 

But damn, does that give me ideas for something else. Do we even have a limit on ROM size anymore? (Starts thinking about how any Turing-complete machine can do literally anything given infinite storage....)

 

Well, Mattel / ECS style page flipping gives you 16 4K pages in each 4K segment. So $E000 PAGE 0 through $E000 PAGE F gives you 64K words. If you apply that to most of the memory map, I think I came up with a theoretical upper limit for the scheme of around 768K words = 1.5M bytes. LTO Flash! tops out at 1Mbyte, JLP tops out around 240Kbytes, and I believe Hive/Bee3 are somewhere in-between based on published specs. (I don't have access to any Hive/Bee3 programming docs.)

 

Obviously, we could extend the Mattel scheme and go ever further.... Instead of writing $xA5y to location $xFFF, we could expand the lower field to more than 4 bits. Anyway...

 

In any case, if you can identify a "working set" and transitions between working sets, it's possible to write a function to manage the page flip, and that function need not be very expensive.

Share this post


Link to post
Share on other sites
Does IntyBASIC attach to the areas listed in the memory map but not listed in its documentation ($4000-$4FFF, $7000-$7FFF, $8040-$9FFF) in order to store variables? What about its prologue/epilogue routines? Clearly those routines have to go somewhere, but I'm a little confused about what determines where they show up. The prologue looks like it starts at $5000 and it looks like the epilogue is using some of the address space in the $4000 block to store some routines, but is there any extra space that can be squeezed out of these areas?

 

There is no ORG directive at the beginning of the epilogue. Do those routines just go wherever the compiler's location counter happens to be pointing when it goes to include this? Will I need to worry about the epilogue writing itself to bizarre or inappropriate places if my code stops near one of the memory boundaries, or will the BASIC compiler make sure that doesn't happen?

 

It appears the rest of the crowd has filled in answers for most of your questions.

 

For the small windows of available addresses, such as $500 - $6FF, it's usually not worth it for a cartridge design to try to fill those areas, or worth it for a game programmer to try to fill those locations.

 

My goal in listing out the semi-exhaustive list of "These are locations that work and these are locations that don't, and under what circumstances" was to provide a more comprehensive analysis for all possible uses of the Intellivision hardware.

 

For game programming, we typically want to stick to the address ranges that give us large, contiguous blocks of ROM, and if we need extra RAM, map it at places where most of the RAM doesn't cause untoward side effects.

 

The Intellivision memory map is riddled with amazingly obscure pot-holes!

 

On the topic of extra RAM: That really comes down to the various cartridge designs. JLP (my own design) prefers (but isn't locked to) mapping additional RAM at $8040-$9F7F. There are good technical reasons for picking that address range; however, other address ranges work as well. That particular aspect will come down to whatever cartridge board design you target, as that cartridge design will need to provide the extra RAM.

Share this post


Link to post
Share on other sites

These responses are all amazing -- thank you so very much.

 

 

If you are worried about level maps taking up too much space we can probably work out ways to compress/decompress them so they take up less space.

 

Yeah, I think I might concoct some sort of simple RLE scheme for the map tiles -- it's not the best compression of course, but it's very quick and really simple to manage.

 

 

Here's a simple if crappy page flipping demo in IntyBASIC. In this example, LEVEL indicates a level number 0..5. The code assumes two LEVELs can fit on a page, and that you'll be reading level data via READ.

 

More sophisticated approaches are definitely possible.

 

Still, this demo does demonstrate it's possible to use page flipping from IntyBASIC.

 

One sad aspect: There is a bug in older versions of jzIntv that prevents it from page flipping page-flipped segments that are a size other than 4K correctly. This code includes an ASM macro that works around it. This macro isn't required by IntyBASIC or AS1600, but rather to work around a bug in jzIntv. It's fixed in the latest development build (and in the version on the jzIntv website), but not in 1.0-beta4.

 

 

 

This example was extremely helpful (thank you so much!), but I don't know if I can use this information for the contest or not. I'm under the impression that it needs to fit on a Bee3 board and I don't *think* they page from what I researched, although I don't know for sure. I know the contest rules don't explicitly state that it has to be playable on one, but the top prizes for the contest include having the winning game put on one of them and I want that game to be mine. ;)

 

(Actually, on looking closer, now I'm not at all sure. The post introducing the Bee3 is a little vague on the details given that it's an introduction and all, but it states the cartridge memory can be expanded. I have no idea how to go about coding for that though.)

 

 

For game programming, we typically want to stick to the address ranges that give us large, contiguous blocks of ROM, and if we need extra RAM, map it at places where most of the RAM doesn't cause untoward side effects.

 

The Intellivision memory map is riddled with amazingly obscure pot-holes!

 

No kidding! I'll try to stick to the beaten path.

 

---

 

You all are absolutely incredible and so helpful. Thank you again!

  • Like 1

Share this post


Link to post
Share on other sites

This example was extremely helpful (thank you so much!), but I don't know if I can use this information for the contest or not. I'm under the impression that it needs to fit on a Bee3 board and I don't *think* they page from what I researched, although I don't know for sure. I know the contest rules don't explicitly state that it has to be playable on one, but the top prizes for the contest include having the winning game put on one of them and I want that game to be mine. ;)

 

(Actually, on looking closer, now I'm not at all sure. The post introducing the Bee3 is a little vague on the details given that it's an introduction and all, but it states the cartridge memory can be expanded. I have no idea how to go about coding for that though.)

 

If it doesn't work on a Bee3 board, I'll be happy to provide a copy on a JLP board, free of charge, without hesitation. JLP can take games up to around 240K bytes using Mattel-style page flipping. I'm not associated with the contest (and in fact I may enter). But I'd hate to see someone not have their winning entry immortalized in hardware due to an incompatibility like that.

 

That said, I don't see why it would necessarily be incompatible with Bee3, though. This page flipping scheme is over 30 years years old and has been documented for quite some time. From what I can tell, Bee3 uses a similar hardware implementation approach to JLP, and so should be able to handle page-flipping. (I haven't seen GroovyBee's specs or documentation. He's seen mine, so maybe he can comment on the differences in more detail.)

 

Above all, I'm more than happy to see folks pushing the Intellivision to its limits. That's why I built jzIntv, SDK-1600, JLP, and so forth, contributed to the IntelliWiki, Intellicart and CC3, and have been contributing to IntyBASIC where I can while working on LTO Flash!.

 

Let's see your awesome Rogue-like game!

Edited by intvnut

Share this post


Link to post
Share on other sites

Hive supports Mattel and Bee3's non-Mattel methods of accessing memory in data bound games. For the contest I would stick with no bank switching for now. If the winner wants to add more things to their game after the contest closes e..g. more/bigger levels, music, high score league/progress saves etc., we can look at suitable cart options then.

 

Edit: Fixed non intentional bad typo

Edited by GroovyBee

Share this post


Link to post
Share on other sites

@petit chou,

 

Why don't we work on getting a game first before worrying about its theoretical size and the physical boards that it could or couldn't use?

 

Have fun, play with IntyBASIC, and post your progress or questions as you go. :)

 

-dZ.

  • Like 1

Share this post


Link to post
Share on other sites

Hive supports Mattel and Bee3's non-Mattel methods of accessing memory in data bound games.

 

If you care to document those additional methods, I can support them in jzIntv, AS1600 and so on for everyone's benefit.

Edited by intvnut

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