Jump to content

Recommended Posts

Does anyone have / have written a compact, no menu / no nonsense one exe file loader for Atarimax carts? Or any existing open-source development that has one? I mean something minimal I could attach my exe file to and have it loadable from the cart.(Actual reason - my game is on the border of using up the whole 1Mbit cart and I cannot afford to have a full 8K block for the Atarimax original "firmware", which otherwise worked for me as it should, essentially I need to have full control over it to squeeze everything). Thought I'd ask before diving into writing one myself. 

 

(A flashing / writing procedure for a single sector of the 1Mbit cart would be also very useful, so far I have found one for the 8Mbit cart, otherwise I know the Arcade Pacman has one, just a bit lazy to dig it out from there ;)).

 

Finally, is it my correct understanding that the flash sector size on the 1Mbit cart is 16kbits, so 2KB, in size? That's about the largest that would work for me, if it is 64kbit that I understand the 8Mbit one has, then the whole topic can be essentially slashed, because I'd need to go the 8Mbit route anyhow...

  • Like 1
Link to comment
https://forums.atariage.com/topic/359893-bare-loader-for-atarimax-cartridges/
Share on other sites

So these are sector sizes in KBytes, huh? Now that you quoted the chip ids I could check for sure. That means no go with the 128K cart, not unless I compress things to squeeze 10K out of my code, probably not doable. Alternatively, to maybe speed up loading, I can load graphics totally uncompressed and then not feel guilty about using an oversized cart 😀 In the meantime I started scribbling a loader just in case, does not seem to be too difficult.

 

Anyhow, I think I see the path now.

  • Like 1

I clearly underestimated the potential of proper compression (I used a quickly self-hacked RL one so far), first experiments show I can save exactly 43521 bytes on the graphics alone (and I also have a 4K Pokey tunes file to do, it is "airy", I expect another 2-3K gain here). Not only it will fit nicely on the 1Mbit cart leaving one full sector free for high score saving, it will also leave another sector for the original MaxFlash firmware (I am still tempted to write my own one though), not to mention that the disk version of the game will now fit on an SD 90K disk. This is toooo good! The only thing I do not yet know is the implication on the speed of loading, this is with ZX5, but how bad can it be ;) 

  • Like 1

I tend to first try simple zipping of data on pc when I wanna check what to expect from compression. Turns out it's almost exactly what you get in the end after using some best-for-the-job packer on 6502 :)

Recently I've used b2 packer and am very satisfied with it.

Read good stuff about zx5 so sounds like a good way to go.
Good luck!

 

  • Like 1

Careful on the flash sector sizes, the flash chip used in the AtariMax carts has changed over time -- in 2012 some additional flash chip IDs were added to the AtariMax flashing software. One of them is possibly the SST39SF040, which has a sector size of 4K instead of 64K. It's hard to tell conclusively as the software checks for the OR of the two flash ID bytes.

 

 

  • Like 1
25 minutes ago, phaeron said:

SST39SF040

Also the SST29SF040 should work, I believe you can get away with their 020 or 010 too. I have a handful of SST29F010 but you can seem to get them for love nor money these days... great thing about them was the sector size is 128 bytes so you can effectively remap DOS operations onto it

  • Like 1
20 hours ago, phaeron said:

Careful on the flash sector sizes, the flash chip used in the AtariMax carts has changed over time -- in 2012 some additional flash chip IDs were added to the AtariMax flashing software. One of them is possibly the SST39SF040, which has a sector size of 4K instead of 64K. It's hard to tell conclusively as the software checks for the OR of the two flash ID bytes.

 

 

 

I read the note on sector size differences in your hardware manual, quite aware of that ;) But now I am getting totally confused - which AtariMax cartridge has what possible sector sizes? The one I am currently (and successfully, see below) aiming is the 128KB one, so this is the sector size I need to know, from previous conversations and various sources it should be 16KB, no? (and only?) Please explain, confirm @Wrathchild ? @phaeron ?

 

One thing I did not find in the reference manual though is how the flashing is done ;)

 

Anyhow, the experimentation with compression totally exceeded my expectations, from ~124000 bytes I went down to ~64300 bytes, this is almost 60K of data saved, on a file that already used (poor, apparently) RL compression. I could still squeeze some bytes out by heavily reorganizing loading order, but I am happy with the end result, extremely happy. Putting aside two nasty mistakes I made at the beginning that stalled me for 2 hours, it all went smooth. One thing I noticed though, in emulation and with this game (lots of on the fly transfers to VBXE) it loads visibly slower from the cart, than when loading the XEX from SIDE3. 

1 hour ago, woj said:

I read the note on sector size differences in your hardware manual, quite aware of that ;) But now I am getting totally confused - which AtariMax cartridge has what possible sector sizes? The one I am currently (and successfully, see below) aiming is the 128KB one, so this is the sector size I need to know, from previous conversations and various sources it should be 16KB, no? (and only?) Please explain, confirm @Wrathchild ? @phaeron ?

The problem is that there isn't necessarily a defined sector size for AtariMax cartridges. That's determined by the specific flash chip used, which in turn may be changed in different production runs -- and the AtariMax flashing software doesn't necessarily use the functionality you're trying to use. The best that you can do is try to accommodate the sector sizes and sector erase procedures for all of the flash chips that are known to have possibly been used, and hope that there isn't a future production run that uses a new chip with another incompatible change. At a minimum, it looks like you might have to accommodate 64K and 4K sectors.

 

The flash chips I have mapped in Altirra for the 8Mbit cart are:

  • Am29F040B ($01/$A4)
  • BM29F040 ($AD/$40)
  • HY29F040A ($AD/$A4)
  • SST39SF040 ($BF/$B7)
1 hour ago, woj said:

One thing I did not find in the reference manual though is how the flashing is done ;)

I haven't documented it in the hardware manual because it's not really new, being well documented in the flash chip datasheets. The hard part is figuring out what flash has been shipped in product and homebrew Atari projects don't document this or note production changes.

 

Flash chips in Atari homebrew are almost universally NOR flash with an interface modeled after the 29F series, which involves unlocking the device by a series of writes with specific addresses and values before being able to issue commands to program or query the chip. More specifically, they're usually modeled after the protocol used by later revisions of the Am29F0x0 series, which changed the unlock protocol from testing A0-A14 to only testing A0-A10. The manufacturer/device ID is easy to query after that, but making sense of it can be tricky because of the dozens of mergers that have happened through the industry, which means you may have to track through two mergers and three rebrands to find out wtf the current name of the company is and where their datasheet is, or conversely what the original name was to find it in archives.

 

Beyond that, the commands for query, program, and erase are pretty regular, though there are still some differences. Sector size is the most common difference; many of the older devices have 8 sectors regardless of size, some newer ones have 4K or even 128 byte sectors, and flash devices with top/bottom variants can even have irregular sector sizes. A couple of devices, though not seen in AtariMax carts, only allow programming in small blocks rather than single bytes and don't allow re-programming areas without an erase. Unlock can still differ, SSF39SF010/20/40 is one of the devices that still requires full A0-A14 unlock.

 

Final note: Altirra doesn't emulate some flash features such as toggle bits, because program/erase operations are instant.

 

  • Like 2
11 minutes ago, phaeron said:

At a minimum, it looks like you might have to accommodate 64K and 4K sectors.

Also for the 1Mbit cart?

 

Anyhow, thanks for the elaborate explanation, as always ;) I developed boot mode flashers twice in my life for two different kinds of ST10 ECUs, so indeed I know that doing this properly is a bit more than 5 minute work, and these were not the most enjoyable programming jobs. I will need to look into these flash chips a bit more it seems...

6 hours ago, woj said:

Also for the 1Mbit cart?

Missed that you were only targeting the 1Mbit cart. Less well researched... the 2012 flasher only accepts two OR values, $20 and $21. Best guesses are:

  • $21 -> AMD/Spansion Am29F010B ($20/$01); 16K sectors with A0-A10 unlock
  • $20 -> ST Microelectronics M29F010 ($20/$20); 16K sectors with A0-A10 unlock

 

  • Thanks 1

I sort of got it to work, so far in the emulator and I have a slight graphics glitch when flashing the sector, for a reason known to me, but I might want to delay fixing it until I have the real cart in my hands, as I presume the timing of things is going to be different. So far I am still using the Maxflash tools loader, I do want to write my own though, first, I think a small speed improvement can be made with buffering, second, so far I did not manage to make it play nice with the RESET button. I noticed the Arcade Pac Man has a nice bare loader for this cart, but it just copies whole continuous 8K block at a time, rather than the XEX file blocks with the initad calls and all, which is what I really need. 

  • Like 1

Feel free to PM me. For reset handling on AtariMax, one of the best ways is to have the cart setting and INI/RUN vectors in every bank, that transfers control back to the main bank. I appreciate that can break continuing of data crossing banks but is managable.

5 minutes ago, Wrathchild said:

one of the best ways is to have the cart setting and INI/RUN vectors in every bank, that transfers control back to the main bank

Yes, I figured out that much and continuity is not a big problem. What I do not yet know is what to expect when none of the banks are active at the time of reset, which is what my game has. But I will figure it out once I get to loader writing.

If you have an indeterminate banking status which will be the case practically always, you'd need to ensure you don't inadvertantly have set up a run environment where the OS attempts to init or run the cart based on the flags value.

So you'd need to ensure $BFFC is nonzero in each bank that doesn't provide a set of valid vectors and init code.

 

Also, isn't there some situation where the default startup bank is different depending on the cart revision?

Erase clears to $FF, so at least the clean sectors should default to not-a-cart.

 

It was the 8Mbit carts that changed default power-up bank behavior at some point between production runs. Probably not anything actually guaranteed, but it was consistent enough that there were definitely cart images that depended on a specific power-up bank and broke on the new run of carts. What's not known is whether there was ever any reset logic involved or whether it was literally the state some random circuit tended to power up in. In any case, it only mattered on a cold power-up start, you couldn't depend on it for any warm start or 'lukewarm' soft cold start scenario. I never actually checked what banks the 1Mbit carts preferred.

 

  • Like 1

Possibly of use, but only for the 8mbit carts. There will be equivalent for 1mbit presumably.

From an Email with Steve Tucker:

 

> At some point I'd like to try adding a high score saving function as

> well, so it'd be good to know the proper way of flashing the cart

> without relying on my interpretation of a disassembly (and potentially

> wrecking my cart!)

 

Hi Chris,

 

Here is the code I used to save game states for Summer Games. The stuff

  at the end is game specific and probably no useful, but the other routines are

  general purpose calls for erasing a bank and writing from a block of memory

  into the erased area.

 

If you need any help just yell. :)

 

Thanks

 

Steve

--

;;

;; XL/XE Equates

;;

inter .equ $3FA ;; Shadow of cartridge interlock

cartop .equ $BFFF ;; Last byte of cartridge

trig3 .equ $D013 ;; Wired to cartridge on XL/XE

random .equ $D20A ;;

zerobank .equ $D500 ;; Zero bank

 

;;

;; Flash program registers

;;

copysrc .equ $30 ;; Source pointer

copydst .equ $32 ;; Destination pointer

cursec .equ $34 ;; Current sector base

curbank .equ $35 ;; Current absolute cart bank

count .equ $36 ;; 16-bit count of data to read/write

pollsame .equ $39 ;; Write polling scratch register

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Set bank to the base of a 64k 'sector' in flash cartridge

;;

;; Valid sectors are 8-15 for an 8mbit cartridge, passed in A

;;

 

setsec sta cursec

and #$0F

clc

rol A

rol A

rol A

tax

sta zerobank,x

sta curbank

rts

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Erase a 64k sector of an 8mbit flash cartridge

;;

;; Valid sectors are 8-15, passed in A

;;

 

erasebk pha

_ebc1 jsr cmd_unlock

lda #$80

jsr wr5555

jsr cmd_unlock

pla

jsr setsec

lda #$30

sta carbase

jsr poll_write

rts

.export erasebk

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Increment the source pointer, dec the 16-bit byte counter, carry will be clear if it turns over

;;

 

decctr inc copysrc ;; Increment the source pointer

bne _dcdst

inc copysrc+1

_dcdst inc copydst

bne _dccmp

inc copydst+1

_dccmp lda copydst+1

cmp #hi(cartop+1)

bne _decby

inc curbank

lda #hi(carbase)

sta copydst+1

_decby sec

lda count

sbc #$01

sta count

lda count+1

sbc #$00

sta count+1

rts

 

         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

         ;;

         ;; Program upto 64k into a sector of the flash cartridge.

         ;;

         ;; copysrc should be set to the start of data to program.

         ;; count should be set to the total number of bytes to write (0 based)

         ;; sector to write to should be passed in A

;;

         ;; you should call erasebk with the sector to erase before programming

         ;;

 

prgsec jsr setsec

 

_prgnw lda #lo(carbase)

sta copydst

lda #hi(carbase)

sta copydst+1

 

_prg1 jsr cmd_unlock

lda #$A0

jsr wr5555

ldx curbank

sta zerobank,x

ldy #$00

lda (copysrc),y

sta (copydst),y

jsr decctr

bcs _prg1

 

_prgerr rts

.export prgsec

 

         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

         ;;

         ;; Program Initalization and Cleanup

         ;;

 

init lda #$00

sta nmien

sta wsync

rts

 

         ;;

         ;; Cleanup routines

         ;;

 

cleanup sta cartoff

sta wsync

lda trig3

sta inter

lda #$40

sta nmien

         rts

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Poll for flash write operation to complete

;;

 

poll_write lda #$00

sta pollsame

_poll_again lda carbase

cmp carbase

bne poll_write

cmp carbase

bne poll_write

cmp carbase

bne poll_write

inc pollsame

bne _poll_again

rts

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Send unlock sequence

;;

 

cmd_unlock lda #$AA

jsr wr5555

lda #$55

jmp wr2AAA

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Shortcut to write a few commonly used 17-bit addresses

;;

 

wr5555 sta $d542

sta $b555

rts

wr2AAA sta $d541

sta $aaaa

rts

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Write @ sector 2ce from $6320, 2 sector

;;

wr2ce jsr init ;; c4a -> cea9 -> pos 4da

lda #$08 ;; flash sector 8

jsr erasebk ;; 02 sectors from 6320 to sector 2CE/2CF

 

lda #$20

sta copysrc

lda #$63

sta copysrc+1

 

lda #$FF

sta count

lda #$00

sta count+1

 

lda #$08

jsr prgsec

jsr cleanup

rts

.export wr2ce

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Shared memory copy routine. Pass table offset in X

;;

memcpy lda #$00

sta copysrc

lda #$A0

sta copysrc+1

lda readtab,x

sta copydst

inx

lda readtab,x

sta copydst+1

inx

lda readtab,x

sta count

inx

lda readtab,x

sta count+1

inx

lda readtab,x

tax

sta zerobank,x

_cpsec ldy #$00

lda (copysrc),y

sta (copydst),y

jsr decctr

bcs _cpsec

rts

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Flash reads

;;

;; dest pointer count (zero based) bank flash sector disk sector

readtab .byte $20, $63, $FF, $00, $40 ;; 8 2CE/2CF

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Read entry points

;;

 

rd2ce ldx #$00 ;; c09 -> cf02 -> pos 499

jsr init

jsr memcpy

jsr cleanup

rts

.export rd2ce

 

.end

--

--

FREE SHIPPING SALE: http://www.atarimax.com/freeshippingsale/

--

     * * * Author of Imagic and APE - The Atari Peripheral Emulator! * * *

     * * * Turn your 8-bit Atari into a p

owerhouse with APE! * * *

    * * * Ape Homepage: http://www.atarimax.com/ * * *

  * * ********************************************************* * *

!! Request my *FOR SALE* LISTING OF CLASSIC VIDEO GAME STUFF -- 2000+ Items !!

  • Like 2

I got a basic custom loader for the cart working, this was not too much work, but I chased myself totally into a corner trying to see what I can do about RESET functionality. I will not write an essay here (too tired by now, perhaps the solution will come tomorrow after rest) of what I just went through, but just ask a direct question:

 

Assuming the cart is not plugged in or disabled, there does not seem to be any way with the Atari OS to configure the dosini / dosvec / casini / boot flags / cold / warm start flags to prevent the OS to open the editor upon RESET, before it goes into any of those handlers, is there? I looked at the XL OS sources, and I do not see a way...

 

(The editor opening is a huge pain for me, because it destroys part of the memory that my game occupies, while I want the RESET to essentially restart my program, and I do not have enough free RAM left to release the area that the editor opening destroys...).

  • Like 1

Even with a cartridge, the OS will often open E:

 

There's only 2 ways to stop the text screen appearing (disregarding using PBI Rom override)

1. have the cartridge run as a Diagnostic mode Rom.

2. normal mode cartridge - do not return from the INIT vector call.  This has indirect JSR before E: is opened.

Both cases mean you don't have a fully initialised system (1 actually means you have to do everything yourself)

 

The additional problem you'd have is that E: could open at $9C00 or $BC00 depending if the flash Rom is present or not.

Could you rework the game such that workspace or screen data is at those locations?

 

Edited by Rybags
  • Like 2

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