GAMEX - should mean something
like 'gaming extra', 'games exitable'. It is intended for old Atari ST
and compatible machines. I tested it on diverse Atari ST(E), Mega ST(E)
and Falcon.
Purpose is making gameplay and especially saves/restores of game
progress (gamestate) more user friendly and compatible with modern
storage devices.
It is intended mostly for usage with hard disks, but may work with
floppies too (except GOS4, 5). Typical savefile is 512KB long - for
games working on
512KB machines.
Principle of gamestate saving: user may interrupt game at any
position with keypress (usually F9). Then code for storing machine
state activates and saves complete CPU, RAM and peripheral chip, video
etc. states. It is known system for decades, made for many of old
microcomputers. Usually such systems had special HW add-on with some
button for interrupt game (or any SW). Gamex is pure SW solution and
therefore requires special adapting of games, so they can be
interrupted.
Gamestate saving in form of snapshots is also a way to save game
adapter from digging in game code - seeking ingame pos. save/load code,
and modifying it for hard disk instead floppy. It may be not simple by
some games, so I think that general machinestate save is better
solution, less work. Not exactly a replacement for ingame saves, but
has some benefits - as faster pos. restoring and
possibility to save pos. even at places where it is not allowed with
game's regular savings.
Restoring gamestates: it is made with little GUI program. It
offers something not much seen: restoring gamestate currently in RAM.
Idea for it came from fact that we need extra RAM for many games if we
want to perform some saves on hard disk, or even just want to run from
hard disk. Reason is that most of games
is not cooperative with hard disks (their driver SW), so we need some
tricks (and plus RAM) if want to play such games from hard disks, and
especially if we want to save positions on hard disks. So we need 1MB
RAM for games working with 512KB. Then
we can do some RAM swaps: before game start: lowering RAMtop
(Phystop) for TOS
on 512KB, then copy low system RAM content in top RAM, store machine
state.
After it we load game in low RAM, while some overwriting of GEMDOS, AES
may happen. But it is no problem for games which not load from disk
after start. Then starting game, which must have added code for
detecting Exit key press (called GAMEX key) and machine state storing
code. So, when user wants to finish playing he press Gamex key, and
code activates - it will save machine state in RAM and then low and
half RAM
will swap content. User will find self in Desktop, just as before
launching game. Just there is less free RAM. Of course enough for
launching Gamex utility PRG, with which can continue just finished
play, or saving permanently current gamestate. Or loading and playing
something already saved. There are some options to help later play as
inserting notes in savefiles, infos about used HW, TOS version,
The benefits: user can have stored gamestates (positions,
settings) on hard disk of games not intended for hard disk saves. User
can in few seconds, after couple mouse clicks find himself in certain
positions of games - no need for starting game with launcher and
waiting for all starting sequences.
Gamestate file structure: at beginning there is header which
holds all necessary informations, notes. After it comes raw memory
content of whole RAM from bottom up to end of normal video RAM
location. If there is some data above latest, some extra code is
required, but may be solved different... I try to make it
maximally flexible and expandable, so there may happen some extensions
in future.
Header entries:
* Ofset Meaning
Content
* 0
signature PPGX
* 4
AltRamStart new phystop, $80000 for 512KB games
* 8 Length of Swap
area usually $7FCC8
* 12 TOS restoring code pos
usually $FFD00
* 16 SysSto
pos TOS state
storing usually $FFF80
* 20 Game restore code
pos usually $7FD00
* 24
GameStat pos
varies...
* 28
GameJmp where to jump to continue game -
varies
* 32 GamexKey
code $43 for F9
* 33 GamePosS
code for case of option "save and continue"
* 34 Special IKBD flag
#1 if $14 then force mouse off by
restore
* 35 STE DMA audio flag
...
* 36 Force Timer Data registers - for 4
timers, if not 0 force
* 40 TOS saving loc
- if 0 will be calculated
* 44 Flag for installing extra
files , word
* 46 Falcon cache settings - 1
byte, another byte is validity flag = $CF .
* So far 48 bytes of header low part defined
* Will be some Mega STE, Falcon setting flags
* Header entries for keeping track on what TOS, HW is snapshot made:
* at pos 128
* First textual mode entries for easy reading:
* 128 Machine 8 bytes longest
entry: Mega STE
* 136 TOS V 8 bytes
again TOS 2.06
* 144 TOS lang 4
bytes
ITA,0
* Binary :
* 148 HWdet
10 Binary machine
description
TOS V Major, TOS V Minor, TOS RAM size in 512KB
steps (1 byte only), Machine code 1-ST, 2-STE, 3-MSTE, 4-Falcon, 5-TT
MSTE cache state, Falcon bus state, Language , Real
RAM size (ST(E) only) , Falcon cache state - but use it from
header pos 46, 47 !
* 158 .;... reserved
* Above ones are generated by PRG
* Optional user editable entries:
* 174 Gamex key string ASCII
10
bytes
* 184 Note ASCII 64 bytes
* 248 reserved 8 bytes
* 256 End
Gamex handles not loading of game files, it is on launcher. If there is
need to load some files outside from launcher - as after loading
gamestate, it is on game. But Gamex will do some support by executing
necessary program by need or loading, installing some special files as
modded GEMDOS variants. For beginning I focus on games which not
accessing disks after loading all files at start. Games which work well
with hard disks are not much interesting for 'gamexing'. Games loading
levels from floppy with direct FDC access need in any case some changes
in code. There are diverse options how to avoid floppy access - as
RAMDisk, low level hard disk access (gamecache area on drives) or using
TOS filesystem access.
Of course we need no more progress saves on floppy (idea:
may using place where code for it is ! ).
Improving, expanding: option for
saving gamestate without exiting game. It will work basically in same
way: will reactivate TOS and then will save state with some specific
filename in current DIR, then instead exiting launcher or Util will go
back in game in same way as by continuing saved state.
Gamestate storing steps:
- Detecting keypress and branch to exit code (2). Location in games
is easy to find with Steem Debugger's monitoring.
- Saving CPU registers on stack, Saving stack pointers
- Saving video+palette, STE DMA audio if used, PSG, MFP (needs
little code for correct
read of timer data regs.)
- JMP to stage 2 where RAM swap and TOS restoring is. In stage 2
IKBD state will be checked and stored by need.
Restoring TOS:
- Disable interrupts, Clear some MFP regs, swap low and upper RAM
contents.
- Restoring video, stack pointers, MFP, enabling interrupts, sound
out as signal and killer of remaining sounds of game
- Clear ACIA from possible overload, testing and storing IKBD state
- Resetting IKBD and setting mouse relative mode (for AES)
- Set screen and program exit call - what leads to Desktop
- Note: if instead latest we jump back in launcher we may do there
some things: as saving gamestate, loading of new levels etc...
Restoring game:
- Basically same as restoring TOS. May happen from RAM or from
file. File will be loaded in upper RAM and then flow is same.
- But need to restore STE DMA audio if used, PSG and IKBD states
from saves too.
The RAM swap flow
Restoring game:
Restoring TOS:
Storing only used part by TOS of low RAM, without screen, as we
don't need it by PRG exit. It is max some 150 KB with TOS 2.06 and hard
disk driver installed. Of course, when nothing else is installed.
There is enough place for modded GEMDOS in upper RAM, upper
part. It is about 93KB for vers. 1.
RAM allocation (usage) in case of GOS4,
with 1MB RAM in machine :
860KB-1M
Space for storing TOS state by launch ( 164KB )
|
768KB-860KB
GEMDOS 0.15
|
700KB-768KB
Hard disk driver,buffers - used while playing game
|
512KB-700KB
used by gamestate restoring, some extra purposes
|
0-512KB
GEMDOS workspace (25KB), Game
|
With 2MB or more in machine there is more space for TOS state
storing, and more space for harddisk driver, it's buffers - then
located above 1MB pos.
RAM allocation (usage) in case of GOS5,
with 1MB RAM in machine :
860KB-1M
Space for storing TOS state by launch ( 164KB )
|
830KB-860KB
GEMDOS workspace
|
768KB-830KB
Modded, reduced GEMDOS 0.15, only for file I/O
|
700KB-768KB
Hard disk driver,buffers - used while playing game
|
512KB-700KB
used by gamestate restoring, some extra purposes |
0-512KB
Game
|
Because whole upper 512KB will be filled with game content by
exiting, we need to reload GEMDOS and hard disk drivers in upper RAM by
continuing play from RAM, and of course in case of loading gamestate
from file too.
Main steps when launching, playing game
with GOS5 :
HW detection, storing params. Message, exit if
insuff. RAM. Message, exit if too much low RAM occupied. Lowering
Phystop, TPA RAM to 512KB (in case of 512KB games) or to 1MB by 1MB
games. Change to low res., move screen buffer down. Saving running TOS,
video, MFP params. (for later exit to Desktop).
Display detected HW, ask about cheats (if possible), then may show some
cover pic or whatever.
Loading packed GOS5 executable, depack to dest. Saving low RAM
to safe space (for later exit to Desktop).
Next step is installing of autoboot harddisk driver in high RAM.
In case of own driver (PPTOS/DOS) it means only copy to dest. loc.
(it's PC relative), setting buffers. In case of popular drivers
as Hddriver need to 'boot' and install it again, to dest. loc.
All it requires some special rutines, changed Trap #1 Malloc, setting
proper cookies etc.
Finally we may load game's starting part, performing some changes
there by need, and jump to start.
When game performs some originally floppy access request, the
changed ingame loader activates. It passes required params to GEMDOS
file I/O loading rutine. Then storing CPU, MFP state, and set correct
values for GEMDOS and execute file I/O.
After it restoring just saved MFP, CPU conditions and jump back to
game, with some ret. values by need.
Exiting to Desktop: storing machine state (CPU, PSG, audio DMA if used,
MFP, video, Blitter if used ...), low 512KB content and restoring
launcher TOS state, then just PRG exit, what means return to Desktop.
Gamestate is in upper 512KB RAM (or more by 1MB games).
It was brief description of how it works. First such adapt. was game
Creatures, then Armour-Geddon, ... F1 GP ... Turrican 2.
The positives: multifloppy games may work on machines with only 1MB RAM
(together with snapshot making option). Fast disk loadings even with
many short accesses (Vroom). Often ingame depackers are culprits for
slower level loads. After getting ingame floppy access code, adaptation
is usually relative easy.
The negatives: need to reinstall hard disk driver by launch, by
gamestate restoring (not problem with mine drivers). On Falcon limited
to max. 512MB partitions because of used TOS 1.04 DOS core.
More details in: example
source .
Problems: It seems that we have couple things which can not detect
properly,
so can not have 100% correct machine state saved. First one is STE DMA
audio
- address counter registers are write-only, so we can not know where
exactly
is audio playback in moment of break. It is not fatal - by continuing
game
we will just have some noise for short time, usually under 1 second.
Other problem is with reading MFP timer data registers. Reading values
accurate is possible with sampling for some time, and taking maximal
value.
But in case when timer is stopped it works not. I encountered that
problem
first in game Goldrunner, where Timer A works only by (sampled) voice
playback. Workaround: detetmining data values with Steem Debugger for
instance
and writing them in header. (4 bytes needed for Timers A,B,C,D ). If
there is
0 then use detected value. If non-zero use it.
Current look of util:
At bottom are some RAM addresses shown - considering low and high RAM
occupied. With Free RAM button may release TOP RAM, without reset.
Credits, used literature:
Atari ST Profibuch, 68000 CPU book, STE Devdocs. Devpac 3. Latest but
not
least: Steem
Debugger - without it many things would be much-much harder.
P. Putnik
Latest update: Jan 2010.