The Cookie Jar
===========#==#=======#===============================================#=====
----------------------|The Cookie Jar |-----
===========#==#=======#===============================================#=====
The cookie jar is a table in RAM listing what hardware and software is
present. It is the supported way to find out what machine you are on,
rather than probing registers or reading TOS version numbers.
The pointer to it is the system variable _p_cookie at $000005A0,
documented on the System variables and low RAM page. A null pointer
means no cookie jar exists, which is the case before TOS 1.06.
Reading that variable directly needs supervisor mode. The supported
way to get the pointer from user mode is the BIOS call Setexc, which
reads or writes any system vector by NUMBER rather than address:
Bios(5, $168, -1)
$168 is $5A0 divided by 4, and passing -1 as the vector means read
rather than write. EmuTOS bios/bios.c implements Setexc as exactly
that, computing the address as 4 x num and returning the old value
without writing when the new value is -1. This works on every TOS
that has a cookie jar at all.
Structure: an array of longword PAIRS.
long tag four ASCII characters, e.g. '_MCH'
long value meaning depends on the tag
The list ends with an entry whose TAG is zero. In that final entry the
VALUE is the total number of slots allocated, not the number in use, so
a program installing a cookie can tell whether there is room.
To INSTALL a cookie: follow _p_cookies to the null cookie, check the
count in its value against the number of entries already present, and
if there is room write the new tag and value over the null cookie and
move the null cookie on by one slot. If there is no room, allocate a
bigger table, copy the old jar into it, add the entry, and point
_p_cookies at the new table. To REMOVE one, find it and copy every
following entry, including the null cookie, back by one slot.
Never assume the jar can be extended in place, and never move it
without preserving the entries already there: other software will be
holding tag values, and some cookies are pointers to structures that
must stay valid.
Tags beginning with an underscore are reserved for Atari. Everything
else is fair game, though in practice most well known ones are taken.
===========#==#=======#===============================================#=====
----------------------|_CPU Processor type |-----
===========#==#=======#===============================================#=====
Value is the processor number in DECIMAL in the lowest byte:
0 = 68000
10 = 68010
20 = 68020
30 = 68030
40 = 68040
60 = 68060
So a Falcon reads 30, a CT60 reads 60.
===========#==#=======#===============================================#=====
----------------------|_VDO Video hardware |-----
===========#==#=======#===============================================#=====
Value in the high word:
$0000 ST shifter
$0001 STE shifter
$0002 TT shifter
$0003 Falcon VIDEL
$0004 Milan video
$FFFF no ST compatible video hardware
The low word is a subtype, normally zero.
This describes the VIDEO hardware, which is not always the same as the
machine. Check _VDO when you care what the display can do, and _MCH
when you care what machine you are on.
An accelerator does not change either cookie. A CT60 equipped Falcon
reports $0003 here and $00030000 in _MCH, exactly like a stock Falcon,
so neither cookie can be used to detect one. Look for the CT60 cookie
instead, described under Other tags below. The same applies to _CPU,
which reports 60 on any 68060 board, not just a CT60.
Values confirmed against EmuTOS include/cookie.h (VDO_ST, VDO_STE,
VDO_TT, VDO_FALCON, VDO_NOHARD). The Milan value is not in EmuTOS and
comes from the published Milan and Alive documentation.
===========#==#=======#===============================================#=====
----------------------|_MCH Machine type |-----
===========#==#=======#===============================================#=====
Value, high word is the machine, low word the variant:
$00000000 ST or Mega ST
$00010000 STE
$00010010 Mega STE
$00020000 TT
$00030000 Falcon
$00040000 Milan
$00050000 ARAnyM
$FFFFFFFF no ST compatible hardware
Note the Mega STE is a VARIANT of the STE, $00010010, not a machine of
its own. Testing only the high word will report it as a plain STE.
HOW THE STE MINOR VALUE IS CHOSEN. TOS 2.06 does not hard code it; it
probes, in this order (Atari's own source, tos3x bios/startup.S):
read $FFFF8E09 (SCU GPR1)
no bus error -> $10 Mega STE (Atari comment: "with SCSI")
bus error, then read the IDE status register
no bus error -> $08 Atari's comment reads
"STE with IDE (unknown machine)"
bus error -> $00 regular STE
So $00010008 is not a model at all. It is what any STE with a working
IDE interface reports under TOS 2.06, which is why owners of IDE
equipped STEs see it, and it is the value Atari intended for an
unreleased "STe/AT" or STe-PLUS prototype that had IDE and a 286.
CONFLICT, ST Book: this page gives the ST Book as $00010001. The Atari
Compendium instead lists minor value 8 as the ST Book, and several
later documents copy that. The evidence favours $00010001: Atari's own
ST Book ROM source hard codes it, with the comment "1,1 => Atari STE,
ST-Book", in the branch built only for that machine. Christian Zietz
adds that $00010001 was also earmarked for the never released STPAD or
STylus. Treat minor 1 as the ST Book and minor 8 as "STE with IDE",
and note that the Compendium's labelling of 8 is the odd one out.
Other minor values reported in the wild but not set by any TOS source
seen here: $0001 0100 for the Sparrow Falcon prototype (unverified,
nobody has confirmed it on hardware), and $0000 4D34 and $0002 4D34
for the Medusa T40 without and with SCSI, where the low word is the
ASCII "M4".
PRACTICAL TEST. Because of the minor values above, testing the whole
longword against $00010000 will fail to recognise an STE that has an
IDE interface fitted, which reports $00010008 under TOS 2.06. The
reliable test for "STE but not Mega STE" is: high word equals 1 AND
bit 4 of the low word is clear. Third party IDE add-ons on an STE are
the usual reason software stops recognising the machine.
CLONES ARE NOT DISTINGUISHED HERE. The Hades reports either the ST or
the TT value, and the Medusa the ST or TT value with the M4 variant,
so _MCH alone cannot identify them. Hatari keeps a SEPARATE field for
this when booting Linux, rather than overloading the cookie:
src/lilo.c defines mch_cookie values 0 to 3 for ST, STE, TT and
Falcon exactly as above, and then a distinct mch_type field with
ATARI_MACH_NORMAL, ATARI_MACH_MEDUSA, ATARI_MACH_HADES and
ATARI_MACH_AB40 (Afterburner040). That split is a good illustration
of the limit: the cookie describes the Atari machine being emulated,
not the board it is actually running on.
Values confirmed against EmuTOS include/cookie.h (MCH_ST, MCH_STE,
MCH_MSTE, MCH_TT, MCH_FALCON, MCH_MILAN_C, MCH_ARANYM, MCH_NOHARD).
The Milan and ARAnyM values are additions not present in the older
Atari documentation.
===========#==#=======#===============================================#=====
----------------------|_SND Sound hardware |-----
===========#==#=======#===============================================#=====
Value is a bitmap. A set bit means that hardware is present:
Bit 5 $20 XBIOS sound functions available
Bit 4 $10 Connection matrix (the Falcon crossbar)
Bit 3 $08 DSP56001
Bit 2 $04 16 bit CODEC
Bit 1 $02 8 bit DMA stereo
Bit 0 $01 YM2149 PSG
So a plain ST reads $01, an STE reads $03, and a Falcon reads $1F.
CONFLICT with older documentation: ST NEWS and other early write-ups
give a different assignment from bit 2 upward, inserting a "DMA record
with XBIOS" flag:
Bit 4 DSP
Bit 3 16 bit CODEC
Bit 2 DMA record (with XBIOS)
Bit 1 stereo 8 bit playback
Bit 0 YM sound chip
That shifts the CODEC and DSP flags up by one and has no connection
matrix bit at all. EmuTOS and the Atari Compendium agree with the
layout given above, so the older reading is treated as superseded. It
is recorded because code written against it will misidentify a Falcon.
Bit masks confirmed against EmuTOS include/cookie.h (SND_PSG 0x01,
SND_8BIT 0x02, SND_16BIT 0x04, SND_DSP 0x08, SND_MATRIX 0x10,
SND_XBIOS 0x20).
===========#==#=======#===============================================#=====
----------------------|_FPU Floating point unit |-----
===========#==#=======#===============================================#=====
Value describes both software and hardware FPU support.
Software FPU, bits 20-16:
Bit 20 68060 internal FPU
Bit 19 68040 internal FPU
Bits 18-17 00 none, 01 6888x present, 10 68881, 11 68882
Bit 16 SFP004 present
Hardware FPU, bits 27-24:
Bit 27 68040 internal FPU
Bits 26-25 00 none, 01 6888x present, 10 68881, 11 68882
Bit 24 SFP004 present
"6888x present" means an FPU was detected but the type could not be
determined; 68881 and 68882 mean it was identified for certain.
CONFLICT on where the bits sit. The layout above is the Atari
Compendium's, with a software set and a hardware set. Other
documentation, including the Alive article and several cookie viewers,
describes a single bitmap in the HIGH WORD only:
Bit 5 68060 internal FPU
Bit 4 68040 internal FPU
Bit 3 68882
Bit 2 68881
Bit 1 68881 or 68882 (type not determined)
Bit 0 SFP004
giving the commonly seen values $00010000 SFP004, $00020000 6888x,
$00060000 68882, $00080000 68040 internal, $00100000 68060 internal.
The two readings agree about the ORDER of the flags and about the
values a real machine produces; they disagree about whether bits 20-16
are a "software" set with a separate hardware set above. Atari's own
ST Book ROM simply loads $20000 with the comment "68881 or 68882 as
co-processor (exact type unknown)", which fits both readings. Compare
values against a real machine before relying on the upper set.
===========#==#=======#===============================================#=====
----------------------|_FDC Floppy controller |-----
===========#==#=======#===============================================#=====
Value, bits 25-24 give the format capability:
00 DD, normal 720K floppy interface
01 HD, 1.44MB with 3.5 inch drives
10 ED, 2.88MB with 3.5 inch drives
Bits 23-0 hold a three character controller ID:
0 no information available
'ATC' fully compatible interface, built to behave as though it
were part of the system
'DP1' DreamPark. All IDs beginning 'DP' are reserved for them.
EmuTOS defines FDC_0ATC, FDC_1ATC and FDC_2ATC as $00415443,
$01415443 and $02415443, which is 'ATC' with the density code in the
top byte, matching the layout above.
WHERE THIS BIT COMES FROM: on the Falcon, EmuTOS sets FDC_1ATC by
reading DIP switch bit 6. Its source comment cites Atari's own
"ATARI FALCON030 Service Guide", dated 1 October 1992, which states
plainly that this bit being off means "AJAX FDC chip installed
(support for 1.44MB floppy)". AJAX was Atari's own HD/ED-capable
FDC redesign, manufactured by Toshiba (part number C302096) after
Western Digital could not sustain production of a suitable part; it
is a genuine, Atari-documented component, unlike some other HD
capability claims attached to standard WD1772 date codes that
circulate without a citable source. 'ATC' most likely stands for
something like "Ajax Track Controller" given this direct
correlation, though EmuTOS does not spell the acronym out.
===========#==#=======#===============================================#=====
----------------------|_AKP Keyboard and language |-----
===========#==#=======#===============================================#=====
Bits 15-8 keyboard layout
Bits 7-0 language
Both use the same codes:
0 US English 13 Saudi Arabian
1 German 14 Dutch
2 French 15 Czech
3 UK English 16 Hungarian
4 Spanish 17 Polish
5 Italian 19 Russian
6 Swedish 24 Romanian
7 Swiss French 31 Greek
8 Swiss German 54 Catalan
9 Turkish
10 Finnish
11 Norwegian
12 Danish
The two are separate because a machine can have, for instance, a German
keyboard with English menus.
The short list given in the older Atari documentation covers only
codes 1, 2, 4, 5, 7 and 8 and treats everything else as English. That
was true of the TOS versions of the time; the fuller list above is the
set current TOS versions actually use, taken from Hatari
src/includes/tos.h and EmuTOS include/ctrycodes.h, which agree. Code 0
is US English rather than "anything else", so testing for a specific
code is safer than assuming a default.
Note where the line falls: EmuTOS marks codes 0 to 16 as the ones
Atari itself defined and documented, and 17 upward (Poland, Russia,
Romania, Greece, Catalonia and others) as later additions that were
registered afterwards rather than issued by Atari. The codes are not
contiguous, so do not treat a gap as free. The same numbering is used
in the ROM header and in NVRAM to pick the interface language and
keyboard layout, so a value here should match those.
===========#==#=======#===============================================#=====
----------------------|_IDT Date and time format |-----
===========#==#=======#===============================================#=====
Bit 12 time format: 0 = AM/PM, 1 = 24 hour
Bits 9-8 date format:
00 MMDDYY
01 DDMMYY
10 YYMMDD
11 YYDDMM
Bits 7-0 date separator, as an ASCII character, e.g. "." or "/"
===========#==#=======#===============================================#=====
----------------------|_FRB and XFRB Fast RAM buffers |-----
===========#==#=======#===============================================#=====
_FRB 64K buffer for DMA transfers to and from fast RAM.
0 means no buffer assigned; otherwise the buffer address.
This exists because TT RAM cannot be a DMA target. Anything going to
or from disk has to pass through a buffer in ST RAM, and _FRB is where
that buffer lives. See the TT RAM entry on the Exception vectors page.
XFRB Extended version, points to a structure rather than a buffer:
word version BCD, e.g. $0101
long xflock semaphore
long buffer pointer to the buffer
long size size in bytes, e.g. 64K
long next pointer to the next XFRB structure, 0 if last
The same restriction applies to an ST or STE expanded past 4MB, not
just to TT RAM. Real ST and STE hardware drives only 22 address bits
for DMA, video and STE DMA sound, so anything above $3FFFFF is
unreachable and needs an _FRB buffer in the low 4MB. Hatari documents
this in src/m68000.c and installs an _FRB cookie itself when running
TOS 4.x with extra RAM: it calls Mxalloc for a 64K buffer in ST RAM,
aligns it to a 512 byte boundary, walks the jar to the null cookie and
writes the entry there (src/tos.c). Note that Hatari deliberately
allows 24 bit DMA addresses under emulation when RAM is set to 8 or
16MB, so a program that works there without an _FRB buffer will still
fail on real hardware.
===========#==#=======#===============================================#=====
----------------------|Other tags |-----
===========#==#=======#===============================================#=====
Atari reserved tags, the ones beginning with an underscore, in full.
Those with their own section above are not repeated here.
_SWI State of the configuration switches, where the machine has
them. Mirrors the DIP switch byte at $FFFF9200
_FLK File locking extensions present (see Fopen bits 3-7). Value is
the version of the extension
_NET Networking support in GEMDOS. Points to two longs: producer ID
then version number
_SLM SLM laser printer driver. Value points to an undocumented
structure
_DOS GEMDOS entry point, present from GEMDOS 0.30
_MET MetaDOS present
_OOL PoolFix installed. Value is the PoolFix version
_INF STEFIX active, the patch program for TOS 1.06
_FSR Serial port patch for TOS 4.00 to 4.04
_5MS Pointer to the 200 Hz system timer interrupt vector
_ISO Real keyboard and font nationality, where it differs from _AKP
_INU Number formatting
_PWR Power management unit present
_PCI PCI BIOS present
_USB USB core API driver present
_VDI Milan VDI
_MIL Milan machine. Value $00000001
_CF_ ColdFire CPU
_MCF ColdFire features
_T30 KAOS TOS
_T2W TOS2WIN emulator
_JPD Falcon030 JPEG decoder by Brainstorm
_PKT Packet driver
_AFM Audio Fun Machine
Common non Atari tags worth knowing:
MiNT MiNT or MultiTOS active. Value is the kernel version in hex,
so $0104 is version 1.04
XHDI XHDI hard disk interface present. See the XHDI specification
NVDI NVDI graphics driver installed
SCSI SCSI driver present
PMMU PMMU setting interface
hade Hades clone (all lower case)
__NF NatFeats, the native features interface used by emulators
CT60 CT60 or CT63 accelerator, described below
THE CT60 COOKIE. This is the only reliable way to detect a CT60,
because _CPU, _VDO and _MCH all report the same values a stock Falcon
with any 68060 board would give. Didier Mequignon's patched TOS 4.04
sets it, and the value is a POINTER to an undocumented structure used
by the CT60 CPX, not a flag. The structure holds the thermal and fan
settings:
trigger_temp temperature at which action is taken
daystop day shutdown setting
timestop time shutdown setting
speed_fan fan speed
CHECK: the published description of this structure gives the fields as
single bytes in its assembler form but as 16 bit values in the
equivalent C declaration, which cannot both be right. The field ORDER
is agreed. Anyone reading these on a real CT60 should confirm the
width before relying on it. Not modelled by Hatari or EmuTOS.
The last few EmuTOS and emulator additions are not present in the
original Atari documentation. Tag list confirmed against EmuTOS
include/cookie.h and the FreeMiNT cookie jar registry.
===========#==#=======#===============================================#=====
----------------------|The current cookie registry |-----
===========#==#=======#===============================================#=====
The page above covers the cookies that describe HARDWARE, which is
what belongs in a memory map. It is not the complete list.
Hundreds of further cookies have been registered by third party
software over the years, from accelerator drivers and file systems to
screen savers and RAM disks. The maintained registry of all of them,
with the author and purpose of each, is the FreeMiNT documentation:
https://freemint.github.io/tos.hyp/en/bios_cookiejar.html
Treat that page as the current known list. If a cookie is not
described above, look there first. Two things to know about it: it is
a COMBINED cookie and XBRA list, with columns marking whether each
identifier is used as a cookie, as an XBRA identifier, or both, so
not every entry on it is a cookie; and the presence of a tag means
somebody claimed it, not that the software is still in use or that
the value layout has been verified.
That page is also the reference for the jar's own rules, which it
states as: identifiers beginning with an underscore are reserved for
Atari, an identifier should be four ASCII characters, it should be
possible to tell from the identifier which program created it, and
the jar ends with a null cookie whose value is the maximum number of
entries the table can hold.
A useful worked survey of the hardware cookies, with example jars
dumped from real machines including an STE, a CT60 Falcon, a Medusa
T40 and a Milan, is the Alive issue 9 article "Cookies for the
Beast":
https://alive.atari.org/alive9/cookies.php
That is where the CT60 structure, the Medusa and Sparrow _MCH values
and the alternative _FPU reading above come from. It is a magazine
article rather than a specification, so its values are treated here
as reports to verify rather than as authority, and the places where
it disagrees with EmuTOS or the Compendium are flagged in the
relevant sections.
===========#==#=======#===============================================#=====
Sources: cookie tag values and bit masks verified against EmuTOS
include/cookie.h and bios/machine.c; the _MCH machine detection logic
read directly from Atari's own TOS source, tos3x bios/startup.S;
machine type values cross-checked against Hatari src/lilo.c, which
carries the same ST/STE/TT/Falcon encoding plus a separate machine
type field for clones, and Hatari's _FRB handling in src/tos.c and
src/m68000.c; Setexc behaviour from EmuTOS bios/bios.c. Jar rules and
tag registry from the FreeMiNT documentation. Example jars and the
CT60 structure from Alive issue 9. Structure and the older tag
descriptions from the Atari F030 and CT60 Hardware Register Listing
and the Atari Compendium.
===========#==#=======#===============================================#=====