peteym5 Posted September 6, 2009 Share Posted September 6, 2009 I am in the process of making a few games to run on the 128k Atarimax carts. A problem I am having is trapping the reset. I converted one game over from a 128k XEGS supercart by copying the bank that resided in RAM to at $A000 to $8000, changed all the addresses of course. On a XEGS it just re-runs the Cart Init addr at $BFFE. However I do not believe hitting reset changes a MAXCART back to Bank 0 to where the Cart Startup Routines are at. I am looking for a simple solution to this problem. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 6, 2009 Share Posted September 6, 2009 You sure about that? I thought they had one bank always present at A000-BFFF and a selectable one that's at 8000-9FFF. Could be wrong though. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 6, 2009 Share Posted September 6, 2009 Should add some more I suppose... in the case the cart doesn't have a fixed bank and just has <whatever> switched when the user hits RESET: You'd have to take care that the other banks either have their own cart INIT routine, or at least ensure the Cartridge Flag bytes are set such that the cart won't try to run. Otherwise you could get crash issues. In the case of a game, you typically don't have (or allow) a DOS to be present, so you could easily just use the RAM-based Disk Software vector ($C,$D), then set the BootFlag (9) to 1. Or just use DOSINI ($A,B). Quote Link to comment Share on other sites More sharing options...
peteym5 Posted September 6, 2009 Author Share Posted September 6, 2009 AtariMax carts do not always have that bank present. They just occupy the memory between $A000 and $BFFF. I copy routines to ram to do the bank switching. I tried setting $C, $D to a cart init addr, but did not work as well. I even set the Reset Vectors at $FFFC & $FFFD. I am considering putting a small init routine at the begging of every bank, but some banks may be crammed full of data with no room left over, so if someone hit reset at the wrong time, the cart will still crash. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 6, 2009 Share Posted September 6, 2009 Doing a RAM-based OS won't do any good - Reset always sets PORTB banking back to the power-on default ($FF). I guess if the bank is indeterminate on Reset, then you'll need to just make sure that the other banks have a non-zero value in $BFFC. The OS checks for ROM, and a zero value there as part of the warm/coldstart. The C/D method should be fine - you get an "E:" screeen opened which you can't avoid. Carts can get control earlier and avoid that "glitch". Can't these carts also be swapped out completely? You'll need to cater for that since the OS might open a screen around $BC00, only to have that area overlayed by the cart once it's swapped in again. Quote Link to comment Share on other sites More sharing options...
peteym5 Posted September 7, 2009 Author Share Posted September 7, 2009 (edited) Hey Been trying the $0B + $0C method, tried both $01,&$03 at $09, neither seem to work. I had to make sure my game does not use these locations in page 0. I also attempted to write $FF to $08. What happens is it blanks out all the memory from page 0 up to the page $8F. My games usually disables the OS and may use page $02 to $8F. I wonder if I have to set Memlow also to protect certain memory locations. Edited September 7, 2009 by peteym5 Quote Link to comment Share on other sites More sharing options...
peteym5 Posted September 8, 2009 Author Share Posted September 8, 2009 I just found out it has an issue with the cartridge checksum that if it does not match, it resets the computer. It adds up from $BFF0 to $C0EF. Not sure why it also adds up bytes from the OS area. Working on a way to get around this. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 8, 2009 Share Posted September 8, 2009 Ahh... I forgot all about that. That is a definate problem then. I think the best solution might just be to define the cartridge vectors in all banks. A right pain for sure. You can't avoid a Coldstart, so the best policy would be to just define it as a Diagnostic Cart and do all the work yourself. At least that way you don't have a cleared RAM situation. A problem could also arise if you switch out the cart to present RAM - in that case there's nothing much you can do at all. You could possibly save a bit of programming pain - when the user presses Reset, just have the "other" banks jump to some code that switches the cart to the main bank then does a JMP $E474. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted September 8, 2009 Share Posted September 8, 2009 I feel I had to get around this with one of my AtariMax cart images, possibly Mysterious Adventures. Like Rybags says, you need to have the vectors setup in all banks. I'll try find the sources and PM them to you. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 8, 2009 Share Posted September 8, 2009 Additional to that, you need to ensure that $BFF0-BFFF contains the same data, or at least generates the same Checksum. I also remember wondering years ago why they do the checksum the way they do... I think it might be a mistype from the OS development. $BF00-BFFF would be much more logical. AFAIK, there's no way on a standard XL/XE to map anything else to the $C000 area in an "automatic" way, ie without PORTB banking or a PBI/ECI device that overrides the normal memory map. Quote Link to comment Share on other sites More sharing options...
Sheddy Posted September 8, 2009 Share Posted September 8, 2009 (edited) I thought I had Reset dealt with on AtariMax, but it turns out that Atari800WinPlus doesn't emulate something correctly on Reset, so it didn't actually work on real hardware. The OS checksum is a PITA. If you can get the checksum it should be possible to get Reset trapped though. I haven't managed to deal with that yet either. Like the guys are saying, I set the cart header vectors in every bank to point to a little stub of code which is also in every bank in the same place. That code switches to the "initialize" bank and jumps to the initialize routine. wastes cart space. Maybe not that useful, but you can use the couple of bytes where the jump is on all the other banks except the initialize one, for something else, of course. Edited September 8, 2009 by Sheddy Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 8, 2009 Share Posted September 8, 2009 Another idea if space is critical - calculate the Checksum for each bank, then store it in the OS location each time you do a bankswitch. That gives back 10 bytes per bank although would lose some in code and RAM storage overhead. Quote Link to comment Share on other sites More sharing options...
peteym5 Posted September 8, 2009 Author Share Posted September 8, 2009 I have been suspecting it is an emulator issue and I could not test it out on real hardware since I don't have my own cartridge yet. I could only do it with certain banks anyway because some are packed with digital sounds and fonts information. I do miss having a section of cartridge memory always present. The reason why I do doing this is to be able to produce more copies of Tempest Xtreem and future titles in the near future. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 8, 2009 Share Posted September 8, 2009 Sounds logical that the banks can only have a power-on state, but not react on a RESET. There's no such output to the cartridge port, so no way of a device knowing when to reset banking. I think a better scheme might have been for $B000-BFFF remaining constant and the $A000-AFFF area being switchable, but that might increase complexity, plus gives less capacity if only using 8-bit bank numbering. Quote Link to comment Share on other sites More sharing options...
peteym5 Posted September 8, 2009 Author Share Posted September 8, 2009 What end up have to do is block copy the original constant bank to $8000 and have all the other banks mapped to $A000. So it was a flip-flop. The trick I did was put in LDA #xx, STA $D500 at the start of the banks I could do, including bank 0. That way when the bank changes, it would end up on the 3rd instruction of bank 0 (5 bytes in, $A005). Any banks containing subroutines at the start call to $A005, instead of $A000. This does open up more for self-modifying code and having the RAM available under the cart area. I will build future games around that, and possibly a future version of Tempest. That is if there is demand for another version. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted September 8, 2009 Share Posted September 8, 2009 I had this code at the end of each bank so that it equates to $BFF4, regardless of the bank present, except for the first: CartGO: STA $D500 JMP CartStart ; Start Address .word CartGO ; Cart present .byte $00 ; Init & Start .byte $04 ; Init Address .word CartGO Instead, (for 128K cart), bank zero contains this code, starting at $BFF7 instead: CartGO: JMP $E477 ; Start Address .word CartStart ; Cart present .byte $00 ; Init & Start .byte $04 ; Init Address .word CartBoot Hence the Reset when a non-zero bank was loaded would cause the CartGo to be called. At this point A=0 and so bank zero is loaded. The program counter is now at $BFF7 and so the Reset is called again. This then causes the cart to vector through to your CartStart address. My CartBoot, called when the cart is powered up, essentially copies the CartStart routine from ROM to RAM and so the CartStart is available to be vectored to, i.e. the OS using JMP ($BFFA). Hope that makes sense Regards, Mark 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.