If I was to write an Amiga game, what would be the best/most reliable way to detect how much RAM is actually available?
The routine you're quoting is only able to detect chip memory (not fast memory), by hardware banging in certain areas. Games sometimes tried $C00000
(popular slow memory location) in the same fashion. But there are too many fast memory configurations to try to detect them that way. The system doesn't do like that (autoconfig works better, and other non-autoconfig boards have software that declare the available memory areas to the system)
Games sometimes did that on the $200000
address without checking the mirror effect (because they didn't expect chip memory to be more than one megabyte). And that failed.
But even games that end up taking over the system use AllocMem
on boot (with MEMF_CHIP
or MEMF_FAST
) to get a base value, mask it to try to guess the start of the memory (and then destroyed the OS). It worked rather well on boot because no other program is using up any memory at this point.
And games not taking over the system can just use AvailMem
with MEMF_LARGEST
flag combined to MEMF_CHIP
or MEMF_FAST
to try to predict if the subsequent allocations that they're going to perform are going to succeed (else they can print an error message and exit). A lot of games don't predict it and if there isn't enough memory the game will fail at a random point of the game...
move.l 4,A6
move.l #MEMF_CHIP|MEMF_LARGEST,d1
jsr _LVOAvailMem(a6)
cmp.l #$80000,d0
bcc.b .one_meg
; 512k only
...
.one_meg
MEMF_LARGEST
is not absolutely necessary. It just tells that you can allocate that much memory in one go and it will succeed. Useful when you want to manage the memory block yourself after that.
For fast memory, using MEMF_LARGEST
will return the biggest contiguous memory block. It means that if there are different fastmem areas (Z2 & Z3, slow), you'll only get the biggest one. Use just MEMF_FAST
alone to get the total available fast memory amount.
Unlike some other libraries that need some initialization, the exec library functions are available as soon as the system is running. It works from a disk custom boot sector too.
Another way (maybe cleaner) is to check exec MaxLocMem
, which provides top of chipmem ($80000
for 512k, $100000
for 1 meg, ...)
move.l 4,A6
move.l MaxLocMem(a6),d1
cmp.l #$100000,d1
bcs.b .not_one_meg
The only drawback is when you configure WinUAE with more than 2MB chip, MaxLocMem
doesn't reflect the chipmem size you configured. But that's a corner case among cornercases (the AvailMem
method works even in that case)