Jump to content
IGNORED

Cartridge start with Altirra 2.40/HLE and 400/800


Recommended Posts

Folks,

I am currently having a strange problem when using the Altirra 2.40/HLE kernel. Simply put: The game crashes. Here are my tested configurations (everything Altirra 2.40):

Emulation Atari 600XL/800XL, 16 Kbyte, XL-OS: runs
Emulation Atari 600XL/800XL, 64 Kbyte, XL-OS: runs
Emulation Atari 600XL/800XL, 16 Kbyte, HLE: crash
Emulation Atari 600XL/800XL, 64 Kbyte, HLE: crash

Moreover I found out that the game also does not run on the emulation of the old hardware:

Emulation Atari 400/800, 16 Kbyte, OS-B: crash
Emulation Atari 400/800, 48 Kbyte, OS-B: crash

My game does not use any fancy RAM-techniques, nor does it use many OS-vectors:

CARTINIT: $BFFE
CARTRUN: $BFFA
SETVBV: $E45C
XITVBV: $E462

Looking at SETVBV and XITVBV in HLE reveals code there (many MANY kudos again to Avery Lee for this absolute wonderful piece of software).

Of course, my next step would be to install the (as of writing this) newest version »Altirra 2.50«. But I seriously doubt this could be the cause of the problem.

An idea would be the start-vector of the cartridge. I am »using« a 16 Kbyte cartridge. Could it be I've overlooked the start vectors for the right cartridge ($9FFA - $9FFF)? Those vectors are currently all initialized to zeros though.

Kind regards,
Henrik (Island2Live)

Link to comment
Share on other sites

Not exactly ... but the debugger of Altirra took me onto the right track: It reported a »bad instruction at $00FF«. What the ... how could my program jump into the zero page?!?

There was only one explanation: The start vector for the »right cartridge« which was set to zeros because my current program does by far not occupy the whole cartridge space by now.

So I prepared a 16-Kbyte ROM-image in the way to use two sets of vectors: One for the »right cartridge« at $9FFE which made the screen red and one for the »left cartridge« at $BFFE (the usual one) which made the screen blue.

Now, here are my results:

Atari 600/800XL, OS-XL: blue
Atari 600/800XL, HLE: red
Atari 400/800, OS-B: red

There is only one conclusion: The OS of the Atari 600/800XL did not initialize the »left cartridge« at all probably because there is no »right cartridge slot« anymore. Same goes with XE/XEGS. But on the Atari 400/800 which has a »right cartridge slot« this one is initialized BEFORE the »left cartridge slot« when a cartridge is present. This is the case with a 16-Kbyte-cartridge. And the HLE of Altirra 2.40 emulates this behavior.

So, if you want to make a 16 Kbyte cartridge run on every system, you have to make sure either the »right cartridge present« flag at $9FFC MUST NOT be zero. This forces the OS to not initialize the cartridge at all. Or you have to set the »right cartridge init-vector« at $9FFE to the same value as the »left cartridge init-vector« at $BFFE. This will make all OSs jump to the same start-routine.

I may have overlooked something. But the first solution is the more interesting one because with data scattered all over the ROM area of that cartridge you can arrange useful data to this byte without taking special care to set this NOT to zero.

It's nevertheless a pain in the a**. Does anyone have any idea how to better solve this?

Kind regards,
Henrik (Island2Live)

Link to comment
Share on other sites

You have to make sure the assembler pads your file out to the vector points. The OS will look for diagnostic cart info at BFFC, then will look at 9FFx. Here's the process:

 

800 OS-B's cartridge startup procedure:
-First check for Diagnostic Cart:
-This is done in the first few cycles of operation
-To allow a diagnostic cart to take over before a flaky computer
-crashes.
Lda $BFFC
-If it's zero, then test to see if it's a ROM:
Bne - outta here
Inc $BFFC
Lda $BFFC
-If it's still zero, then it must be ROM!
Bne - outta here
-Is this a "Diagnostic" cart (runs before OS initializes)?
Lda $BFFD
-Bit 7 is the Flag
Bpl - outta here
Jmp ($BFFE)
-outta here: gets us to this point:
-Cartridge was not Diagnostic, so hardware init has now run
-RAM size is verified. Cartridges are only checked if RAM is not
-found in their space.
-Assuming RAM was not found in $8000-BFFF
-Locations $9FFC and $BFFC are checked for 0 values.
-If they are found, an Init routine in the cart is run. It is expected to end in an RTS.
lda $9FFC
bne - next test
jsr ($9FFE) - (actually a JSR to a IND-JMP)
-next test
lda $BFFC
bne - DOS test
jsr ($BFFE)
-DOS test
-Now DOS is loaded if the cartridge so desires.
-$BFFD and $9FFD are OR'ed (only cartridges that passed the above "zero" test are included). Bit 0 means Boot DOS.
And #$01
Beq - No boot!
-Otherwise, DOS is booted.
-Now, if Cart A is present (passed the "zero" test), it can be run if the RUN flag is set:
-No boot! Jumps to here
Lda $BFFD
And #$04
Beq -Try Cart B
Jmp ($BFFA)
-Try Cart B
-If Cart B passed the "zero" test, then see if it wants to RUN.
Lda $9FFD
And #$04
Beq -All Done
Jmp ($9FFA)
- All Done, OS continues...
Note that with a 16K cart ($8000-BFFF) a 0 value in $9FFC will cause an init routine to be run at $9FFE whether it exists or not! Make sure $9FFC is non-zero in a 16K image.
If a cartridge is marked as executable ($9FFC or $BFFC=0) the Init address (xFFE) is always taken. You can point this to an RTS instruction, and then run at (xFFA), or you can simply never return from the Init call, or you can run as a diagnostic cart if you don't need the OS at all.
$9FFA/BFFA - Run Address
$9FFC/BFFC - Zero if cart is executable/Nonzero cart is ignored
$9FFD/BFFD - Flags (if bit set) b7=Diagnostic, b2=Run, b0=Boot DOS
$9FFE/BFFE - Init Address/Diagnostic Run Address
Diagnostic cartridge is signalled at Cartridge A ($BFFD) only.
Link to comment
Share on other sites

First activate the "Stop at BRK" in the CPU options. If that is off, the CPU will runs though all the RAM etc. because it finally finds a location to crash. If the option is on, the debugger stop at the first occurrence of BRK, which is typically right after things went wrong (PLA before RTS/RTI, JUMP($sillyuninitializedvector), ...).

 

if that does not help, just set a break point at the read access to $BFFA-$BFFF and then step in to see what goes wrong.

 

ba r $BFFFA l$6

Edited by JAC!
Link to comment
Share on other sites

Altirra's HLE OS is buggy as fark... I haven't even backported all of the fixes from the pure 6502 version (formerly LLE OS), and as you've discovered, it has problems due to not having separate 800 and XL versions. I'll probably remove the HLE OS at some point.

 

I don't recommend creating diagnostic carts ($BFFC=0). My experience has been that several types of popular physical flash carts do not always handle diagnostic carts properly because their hardware doesn't initialize quickly enough on power-up for the OS to recognize the cart as a diagnostic cart. The result is that the cart doesn't work reliably on a cold boot and sometimes tries to boot as a non-diagnostic cart instead. I've seen this with both MaxFlash and SIC! cartridge hardware.

Edited by phaeron
Link to comment
Share on other sites

There's not any great advantage in doing a cart as diag mode. Given the knowledge base and modern hardware tools and emulation, it's pretty hard these days to do software that can't be looked at or copied without too much trouble.

 

The other thing with diag mode is your software then has to create the machine environment and it's really easy to get it wrong if you expect the OS to handle stuff like NMI/IRQ processing.

 

A good method I've seen used in many games is to just flag as a normal cart, set the flags to disallow boot if it's not a language cart, and just don't return control from the INIT vector.

That way you get a nicely initialized system environment (and save programming in the process) but still have a cart environment that can be just as locked down as if it was done as a diag mode cart.

Link to comment
Share on other sites

@Brian:

Thank you very much for this detailed description of the Atari boot process. If I get this right my method 1 (setting $9FFC to a non-zero-value) or the »diagnostic mode« looks most promising. The »diagnostic mode« has an other benefit: Since I have to take care for all those NMI/IRQ-vectors by myself a game could better be translated to an Atari 5200 (which I am not planning to do).

 

 

@phaeron:

In my case »HLE« is nevertheless most welcome. For booting up a cartridge image and handle some OS jumps it's perfect. I've also tried »LLE« (both as OS-B and OS-XL/XE) and they showed the same behavior as »HLE« (boot right cartridge before left cartridge in a 16-KByte ROM-Image). So the way to go would be to create a cart which runs on both systems (old Atari and XL/XE).

 

Good point regarding the flash-cartridges.

 

 

@Rybags:

I am currently doing exactly this: Do not boot, do not »diagnostic mode« and don't return from init.

 

 

Kind regards,

Henrik (Island2Live)

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

I found an other problem, this time regarding the WARMST flag in zero page ($0008) to distinguish between a cold start (WARMST = 0) or a warm start/reset key press (WARMST != 0). I would love to use this to reset the highscore of the game at power up.

 

When I am ONLY using the init vectors of the cart to start the game, WARMST is not valid, it's always set to zero. But when I am directing the init vector of the cart to an RTS and use the start vectors instead, WARMST is valid.

 

This is the case when using the original OS-B or OS-XL of the machines. Using LLE on Altirra shows a different thing: In this case the WARMST flag is always valid regardless how I initialize the cart.

 

I was close to the point where I about to drop support for the old 400/800, only support XL/XE/XEGS machines and don't care for the whole vector and flag area of the right cartridge ($9FFC - $9FFF).

 

But when using LLE on Altirra with 600XL/800XL it DOES care for the flags in the right cart.

 

Right now I do not see an elegant way how to make a cart run on all real hardware and on Altirra with LLE. It looks like I have to split memory in two 8-KByte parts and take care for the initialization of both carts. :(

Link to comment
Share on other sites

I'd suggest - try testing the COLDST flag $244, should be 00 on warm start.

 

Otherwise, use a magic number flag system to determine what's going on, ie test for 3 or 4 known values in a sequence, if they don't exist then store them there and do coldstart processing.

Link to comment
Share on other sites

I'd suggest - try testing the COLDST flag $244, should be 00 on warm start.

 

Otherwise, use a magic number flag system to determine what's going on, ie test for 3 or 4 known values in a sequence, if they don't exist then store them there and do coldstart processing.

Well ... I don't think it is that simple. Moreover I don't want to reinvent the wheel again and again.

 

The original idea was to create a 16 Kbyte cartridge which

 

a) runs on all real hardware (Atari 400/800/600XL/800XL/XE/XEGS)

b) runs in emulation on Altirra

c) runs on Altirra even with no OS present (HLE/LLE; copyright problems)

d) provide an undivided address space across the 16 Kbyte

 

There is still the idea to create a »diagnostic« cartridge but that would mean to care for all the setup of the computer by myself. Again: I want to program a game and not to reinvent the wheel.

 

So up until now - after some more tests - the best solution would be to do the following:

 

a) threat the cartridge as left and right with both init vectors valid ($9FFA-$9FFFF for right and $BFFA-$BFFF for left)

b) set right cartridge »PRESENT« ($9FFC) to something other than zero to not let that cart start on an 400/800 or on HLE/LLE

c) set left cartridge »INIT« ($BFFE) to a simple »RTS«-instruction; this can be put into $9FFC to not waste a byte

e) set left cartridge »PRESENT« ($BFFC) to $00 to let the OS know »here is a cartridge«

e) set left cartridge »FLAGS« ($BFFD) to $04 to start the cartridge but not boot DOS

f) set left cartridge »START« ($BFFA) to start of the game; this way I can use WARMST the way it is intended to work

 

That would mean to split the address space of the cartridge ... it's not that bad after all, because it's a good training if I am to create a page banked cartridge with more than 16 Kbyte one day. :)

 

Kind regards,

Henrik (Island2Live)

Edited by Island2Live
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...