atari++(6)

๐Ÿ“ฆ version 1.85, in fedora 43, fedora 44, nixos 26.05, nixpkgs unstable

๐ŸŽ€ atari++ ๐ŸŽ€

okay bestie, sit down, hydrate, because this is the manual page for atari++ from the Games Manual section (section 6, iykyk) and it is long. but it's also iconic so let's go ๐Ÿ’…


โœจ NAME โœจ

atari++ โ€” a versatile extended emulator of Atari 8 bit machines ๐Ÿ•น๏ธ


โœจ SYNOPSIS โœจ

atari++ [-option value [-option value]...]

โœจ DESCRIPTION โœจ

so. atari++ is an emulator for those (now rather aged ๐Ÿซ ) Atari 8 bit computers. she emulates the Atari800, the Atari400, the 800XL and 600XL, the 65XE and 130XE, and also the Atari 5200 Game Console. and the emulation is cycle-precise, which means "on the fly" modifications of chip registers show up on the screen immediately โ€” like, even programs using horizontal kernel tricks get emulated correctly. ate. periodt. ๐Ÿ”ฅ

atari++ also includes emulation of various disk drive models, capable of single, enhanced and double density, plus some frequent extensions found in third-party hardware. the disk drive emulation supports disk images in the xfd and atr file format, and it's also capable of loading binary load files (so called exe files) by emulating a mini Game-DOS whose disk layout is similar to Dos 2.0S. so most exe files wouldn't require being loaded from a regular DOS at all. ๐Ÿซถ and as a bonus, the emulation also includes Matthias Reichl's "atarisio" interface, which lets you connect a real 1050 or 810 drive to the emulating PC by means of a 1050-to-PC or ProSystem cable. real hardware bestie reunion ๐Ÿ˜ญ๐Ÿ’–

in case no Atari ROM image is available, atari++ emulates a 800XL/130XE ROM image compatible to the Atari ROM that is sufficient to run almost all programs. Basic programs are supported by the built-in Basic emulation that is also compatible to the native Basic ROM. slay โœจ

Emulation of printers is included as well. Print-out text is forwarded to the standard printer tool, which defaults to the lpr printer front-end. The print-out command can be adjusted by means of the command line options and the configuration files (see below).

Additional features include emulation of the 850 serial/parallel interface box, emulation of the tape drive, a screen-snapshot, a complete machine state save and load feature that allows you to stop and replay a game in a later session, and sound support by the Open Sound System (Oss) or Alsa sound drivers. ๐ŸŽง

Furthermore, to aid the developer, a simple system monitor using a curses terminal front-end has been integrated into the emulator. It offers several features not available on the real hardware, as single stepping thru programs and setting breakpoints, even in ROM code. developer main character energy ๐Ÿ‘‘

Graphics output is either emulated within an X11 window, or โ€” if available โ€” with the SDL library. As last resort, and for special applications, some ports provide a curses front-end that renders its output in textual form on a console. Alternatively, the emulator can also be instructed to read and write input to the operating system editor device directly to and from the console, i.e. the standard input and output streams of the program. This is not implemented as a new type of front-end, but rather as an operating system patch. ๐Ÿ“


โœจ OPTIONS โœจ

quite untypical for unixoid systems, the atari++ options are not case sensitive โ€” upper and lower case won't matter. and the order of the command line arguments doesn't matter either. the following options are supported:

  • --help โ€” prints all available options to the console.
NOTE: Due to the dynamic build-up of the atari++ components, the options these components become only available if the corresponding component is activated as well. E.g, you won't see the X11 options with the SDL front-end activated. ๐Ÿ’€
  • -h โ€” similar to the above.

All following options are of four kinds:

  1. Numerical options taking exactly one number as argument. They typically accept only numbers within a limited range.
  2. Boolean options, taking the strings on or true as positive and off, no or false as negative choices.
  3. String options that take either a file or a string as value.
  4. Selective options that pick one out of several possible, mutually exclusive choices.

๐ŸŒธ On the Fly Configuration ๐ŸŒธ

Atari++ provides a quick and a complete menu to setup or modify its configuration on the fly. For the quick menu, press and hold the left mouse button within the emulator window, and pick an apropriate option from the menu on the screen. This menu provides the most-used options, namely to load and boot a disk, to pick a cartridge or to reset the emulated Atari. ๐Ÿ–ฑ๏ธโœจ

The full menu is either available as an option within the quick menu, or by pressing the F1 key on the keyboard. The options presented there are identical to the options listed below.

NOTE: The quick menu is not available in case the mouse has been arbitrated to emulate a joystick or any other kind of input device. You'd need to enter the full menu by the F1 key to adjust the configuration in this case. ๐Ÿ™ˆ

๐Ÿ’œ Global Options ๐Ÿ’œ

This set of options does not belong to a specific part of the emulation core, but rather influence the emulator as a whole.

  • -h or --help โ€” prints out the list of currently available options. This list does, however, depend on the current configuration of the file as options for modules that are currently not in use will not be shown on this list. For example, if your .atari++.conf file selects the X11 frontend for graphics output, the options for the SDL graphics support will not be shown. Unlike all other options, this option does not take an argument.
  • -config filename โ€” Load an alternative configuration file into the emulator. This will override the options from all other configuration files, but will be overridden by the command line arguments itself.
  • -state filename โ€” Load a machine state snapshot file. This restores the machine state of a previous atari++ session by re-installing the memory conents and all hardware register settings of the previous session. For more details about the snapshot feature, see the SNAPSHOT FILES section below.

๐Ÿฆ‹ Machine Type Options ๐Ÿฆ‹

The following options modify the overall emulation process, picks the hardware to be emulated and the frontend how to perform graphics and sound output.

  • -machine 800|1200|XL|XE|5200 โ€” Sets the type of machine to emulate. This is a meta-option that sets suitable defaults for several other options, still allowing to override these defaults with further commands. Hence, you'd be still able to run an Atari XL machine with the Os of the Atari 800. The following models are available:
    • 800 emulates the Atari 800 and its derivative, the Atari 400.
    • 1200 emulates the Atari 1200XL. This is almost identical to the 800XL, except that the default ROM image is different.
    • XL emulates the Atari 800XL, the 600XL and the 65XE.
    • XE emulates the Atari 130XE with a total of 128KByte memory.
    • Last but not least, the 5200 argument selects the emulation of the 5200 game console.
  • -frontend X11|SDL|CURSES|NONE โ€” Defines which graphical front-end should be used. Currently, the X11 the CURSES and the SDL front-ends are supported. NONE is a dummy front-end without any graphical or textual output that can be used for playing music or related tasks. The installedevice option is suggested to get minimal support from the console using only stream-I/O. Note this type of redirection is not a front-end option, but rather an optional operating system patch, see OS Options below.

The X11 interface is only available for Unix based operating systems, most notably Linux, while the SDL interface is currently available on most ports. The latter is also able to run in a full-screen mode that is more suitable for gameplay. Typically, the SDL front-end provides better performance unless you need to scale up the output with the -pixelwidth or -pixelheight options. Then, X11 performs noticeably better. The CURSES front-end requires only a terminal for rendering, but its graphics capabilities are rather limited. Specifically, it is only able to emulate text-based graphics modes and expects the built-in font to render the output. The keyboard mapping for the CURSES output is also slightly different, see the CURSES section for details.

  • -sound HQOSS|OSS|WAV|SDL|ALSA|DIRECTX โ€” Sets the audio front-end used to generate audio output. For the OSS and HQOSS front-ends, an Open Sound System compatible driver is required, or no sound whatsoever will be available. Sound synthesis will be very close to the real sound output and will be at good quality, though some CPU power is required to guarantee continuous output without dropouts. In general, the HQOSS driver is preferably since it requires less precise implementations of the Oss standard and provides excellent quality for synthesized speech.

The main intention of the WAV front-end is to record the sound output as sampled sound in a .wav encoded file in optimum quality. To allow you to listen to in-game sounds, this front-end also offers a "play-back" option that also generates sound output thru an OSS compatible sound output, though this output is of less quality than that of the dedicated HQOSS module. Even though the play-back sound may contain some "blips" or drop-outs, the quality of the recorded audio within the .wav file will be perfect and very close to the original.

The SDL audio generation comes close in quality to that of the HQOSS driver, though it is more likely to generate drop-outs for highly loaded systems. SDL is the best in portability as SDL exists on a variety of systems. The SDL driver also emulates software speech correctly.

The DIRECTX driver is obviously available only for win32 compilations and uses the DirectSound interface of the DirectX system. This is the prefered sound system under Windows as it offers lowest latency at best quality.

Finally, the ALSA front-end uses the state of the art ALSA sound drivers for linux and provides optimal sound quality at minimal CPU load. It provides similar or better quality than the HQOSS front-end at less complexity, but it requires ALSA support, nowadays almost universally available. ๐ŸŽถ


more parts coming bestie, don't go anywhere ๐Ÿ’–

  • -monitoroncrash bool โ€” turn this bad boy on and the emulator will auto-yeet itself into the built-in monitor the moment the 6502 CPU crashes because of a corrupt program. And bestie, listen: those crashes are not the emulator's fault, they're flaws in the emulated program โ€” like, a "real" Atari would have crashed in the exact same situation, no cap. If it's off, you just get a warning printed and the user menu pops up, and it's on you to either reset the emulation or launch the monitor manually. Defaults to false, i.e. the monitor does not enter by itself. ๐Ÿซถ

For all the deets on the system monitor, see the MONITOR section below.

  • -acceptlicence bool โ€” enable this and it's understood that you read and agreed to the licence conditions under which Atari++ is delivered, so the licence conditions stop showing up on startup. Iconic. โœจ
  • -stereopokey bool โ€” toggles the "dual Pokey" hardware hack emulation. This hack installs a second Pokey at base address $d210 into the system, which is what makes stereo sound emulation possible. Atari++ then provides a second Pokey chip named "ExtraPokey" that otherwise takes the same configuration arguments as the first Pokey does โ€” except this second chip is not connected to the serial output and the keyboard.
NOTE: the second Pokey chip is fully functional and also provides interrupts. But since the Atari OS isn't aware of this chip, it can't handle those interrupts. So programs might crash if interrupts of this extra chip are erraneously enabled. This is not the emulator's fault โ€” a real system would crash under the same circumstances. ๐Ÿ’€
  • -ignoreerrors bool โ€” tells the emulator to ignore all error messages and keep going as if the error requester had been closed by pressing "Cancel".
  • -ignorewarnings bool โ€” same energy as the one above: suppresses all warning requesters as if the user accepted the warning.

๐Ÿง  CPU Options ๐Ÿง 

The following options control the emulation of the 6502 CPU:

  • -traceonreset bool โ€” debugging queen behavior. If you enable it with the on argument, the CPU enters trace mode on a reset and goes straight into the build-in monitor. ๐ŸŽ€
  • -traceinterrupts bool โ€” another debugging-related one. Turn it on and instruction stepping will also step into interrupt routines as soon as an interrupt gets detected. This might cause some confusion because, surprisingly, the 6502 CPU will continue execution from a completely different place โ€” though it's genuinely helpful for finding bugs in display list interrupts. ๐Ÿ™ˆ
  • -cputype 6502|WD65C02 โ€” picks which CPU type gets emulated. The WD65C02 offers a couple of addtional addressing modes and instructions that are supported by a couple of products, e.g. the Mac/65 assembler cartridge. Slay. ๐Ÿ’…

๐ŸŒˆ GTIA Options ๐ŸŒˆ

The following options modify the emulation process of the video signal generator, the Graphics Television Interface Adaptor chip:

  • -videomode PAL|NTSC โ€” defines whether the emulated GTIA should identify itself as a PAL or as an NTSC chip. Some games read this value and modify their timing accordingly. This option also changes the color map GTIA sends to the front-end, since colors differ slightly between the PAL and the NTSC version of GTIA. โœจ
  • -ChipGeneration CTIA|GTIA|XLGTIA โ€” selects the chip generation to emulate. CTIA selects the old first generation used in some very early 800 and 400 models โ€” this chip did not provide the special 16 hue/16 luminance and 8 color modes, BASIC modes 9 to 11. GTIA selects the second generation, used in most 800 and 400 models, and XLGTIA the third generation in the XL series. The last two chips do actually not differ โ€” only the surrounding analog circuits change the color artifacts slightly, which is the only noticable difference between them.
  • -artifacts bool โ€” controls whether GTIA should emulate the color artifacts caused by the video system. Set it to on and the video rendering will detect hi-lo and lo-hi transitions for high-resolution graphics and text mode and generate pseudo-colors similar to a real TV. On real hardware these artifacts are limited to NTSC systems and are not as effective nor very visible for the PAL hardware โ€” the emulator, however, displays them regardless of the emulated video mode. Some games require this setting to look properly. Set it to off and artifact generation is disabled, as it would be for a higher quality monitor or for the PAL video system. That also makes text more readable and less blurry, speeds up the emulation process somewhat, and is better suited for text-oriented software. ๐Ÿ‘‘
  • -palcolorblur bool โ€” enables emulation of a feature of the PAL video system standard that can be used to create additional colors by mixing. If two adjacent horizontal lines on top of each other share the same intensity but have a different hue, then the mixture of the colors appears instead of two separate colors. This option is computationally a bit complex and requires a true color display, i.e. a color depth of 24 bit, to be effective.
  • -antiflicker bool โ€” enables the Atari++ flicker fixer. Some programs create additional colors by quickly altering the colors forth and back, causing the mixture of the colors due to the slowness of the TV screen. PC monitors are typically much faster, causing an anoying flicker for these programs. This switch enables a flicker-fixer that mixes the colors already in the GTIA display generation โ€” at the price of a higher complexity. This option also requires a true-color display, i.e. a bit depth of 24 bit. ๐Ÿฆ‹
  • -playerpositiondelay 0..32 โ€” controls the number of half color-clocks required by GTIA to detect any change of the player/missile horizontal position register. It's the minimal screen distance in half color-clocks after writing to the horizontal position register until the change becomes effective. The default for this value is 12, i.e. it takes 12/4 = 3 CPU clocks before a horizontal adjustment is recognized.
  • -playerresizedelay 0..32 โ€” same vibe as above: controls the internal GTIA propagation delay until a change of a player/missile size register becomes effective, and thus the distance in screen hires pixels from the modification to the position where the change becomes visible. The default is six half color-clocks.
  • -playerreshapedelay 0..32 โ€” quite similar again: controls the propagation delay for player shape changes, i.e. how long it takes for a write to the P/M graphics register to propagate to the output logic of GTIA. If the write comes too late, the shape change will become visible only on the next scanline โ€” unless GTIA fetches the data through the ANTIC DMA, of course. ๐Ÿ˜Œ
  • -colormapname filename โ€” wants a filename to a color map to be used instead of the default PAL or NTSC color map. The color map file must be exactly 768 bytes long and contains, for each Atari color, a red, green and blue color triple, eight bits per channel.
  • -playertrigger.0 all|players|missiles|none โ€” the first out of four otherwise identical options. It sets the ability of player zero to generate collisions with other objects on the screen. Note that this does not change the ability of player zero to detect collisions itself โ€” it just removes the ability of other players or missiles to collide with it.

If this option is set to all, then player zero can create collisions with all other objects. For the players setting, only collisions with other players are generated and missiles never see any collisions with player zero. For the missiles setting the situation is reversed and only missiles can detect collisions to player zero. Finally, for the none argument, player zero generates no collisions at all.

  • -playertrigger.1 all|players|missiles|none โ€” works similar to the above except that it changes the ability of player one to generate collisions.
  • -playertrigger.2 all|players|missiles|none โ€” changes the abilities of player two and, finally,
  • -playertrigger.3 all|players|missiles|none โ€” modifies the collision abilities of player three.
Note that there are no options to modify the collision abilities of a missile, since it has none in the real hardware. A missile can never create a collision with a player itself, or any other object. Rather, the situation is somewhat reversed from the expected logic: a player creates a collision to a missile, and hence its ability to collide with missiles must be turned off to avoid detection of player-missile collisions. ๐Ÿงš
  • -playfieldtrigger.0 all|players|missiles|none โ€” modifies the abilities of playfield zero, i.e. the first foreground color, to generate collisions to other objects. Similar to the above set of four options, playfields can be allowed to generate collisions to all objects, players only, missiles only, or no objects at all.
  • -playfieldtrigger.1 โ€” triggers the ability of playfield one to generate collisions; otherwise, similar to the above.
  • -playfieldtrigger.2 โ€” the same again for playfield two.
  • -playfieldtrigger.3 โ€” the same once again for playfield three. ๐Ÿ’œ

๐ŸŽฌ ANTIC Options ๐ŸŽฌ

The following options control the DMA controller and the playfield graphics generator chip:

  • -videomode PAL|NTSC โ€” this option is intentionally identical to the GTIA option of the same name and controls the video system ANTIC should emulate. As for ANTIC, this switch controls the height of the video output. For PAL, a total of 312 lines is generated, and for NTSC, only 262 lines of output are displayed. Note that not all lines are available for graphics, as the vertical retrace takes up some of them. ๐ŸŒธ

๐ŸŽต POKEY Options ๐ŸŽต

Okay bestie, this next batch of options is all about the sound. For actual sound output you need the Open Sound System driver for your sound card โ€” more specifically, /dev/dsp has to actually be there, no cap. Alternatively you can write the sound output into a .wav file and replay it later with some suitable tool, like XMMS. Other possible sound outputs are SDL or Alsa, depending on whether they're available on your system. Peep the Machine Settings section for the deets.

Now here's the thing: the switches below do not change the output of the sound itself. They change the emulation of the POKEY chip that generates the audio signal which then gets processed by the OSS module described below. Two different layers, iykyk.

NOTE: If the โ€œstereopokeyโ€ emulation is enabled, a whole second set of Pokey control options shows up under the topic โ€œextrapokeyโ€. That set is literally identical to the one described right here. โœจ

  • -volume 0..300 โ€” controls the overall volume of the POKEY output, in percent, compared to normal output. 300 is loudest, and 0 disables the output entirely. Default is 100%. ๐Ÿ”ฅ
  • -gamma 50..150 โ€” controls the output linearity of the POKEY D/A converter, in percent. 100% is a perfectly linear output (assuming your sound card output is linear too). Values smaller than 100% give you sublinear behaviour, where high amplitudes look smaller than they should. Values higher than 100% give superlinear characteristics, where high amplitudes are louder than they should be. Real pokey chips typically show sublinear characteristics with a gamma value around 70% to 80%. Iconic honestly.
  • -videomode PAL|NTSC โ€” okay so Pokey isn't a video interface circuit, but its timing is still controlled by the system base frequency, which is tied to the video mode. This option controls whether Pokey thinks it's living in a PAL or NTSC system; it nudges the audio base frequencies slightly. ๐Ÿฆ‹
  • -siosound bool โ€” enables or disables the serial transfer sound, provided the siopatch is not enabled and bypasses hardware driven serial i/o. Turning this on gives you a more complete Pokey emulation, because it also takes care of the serial transfer modes for generating sound. Which means: you get the very unique โ€œAtari sound effectsโ€ for all kinds of disk or tape access. ๐Ÿ’–
  • -cycleprecise bool โ€” controls whether the Pokey emulation works cycle-precise, that is, whether pokey interrupts and potentiometer registers are updated and queried on a cycle by cycle basis. More precise emulation, yes. Also more computing power required, also yes. Pick your fighter. ๐Ÿ’…
  • -filterconstant 0..1024 โ€” controls the time constant for an optional high-pass filter applied to the audio output signal generated by the Pokey emulation. This high-pass filter cancels any DC offset in the sound generation that might cause trouble for audio cards or amplifiers, especially when the audio output level is close to the maximum. The lower the filter constant, the more frequencies get cut off by the filter. Setting the filter constant to zero disables the filter. Default setting is 512.
  • -recordasSAP bool โ€” if enabled, the Pokey output is recorded on every vertical blank into a SAP type R file. In principle, such files could be played back as music files by third party software. Unfortunately, type R does not seem to be well supported at this time. ๐Ÿ˜ญ
  • -sapname name โ€” defines the name of the song currently being recorded, and also the file name the song will be saved under. The file gets created in the directory the emulator was started in, and the file name is generated by appending .sap to the song name. ๐ŸŽ€
  • -sapauthor name โ€” defines the name of the author recorded in the SAP output file. This one may stay unset, in which case an unknown author will be indicated.

๐ŸŽฎ PIA Options ๐ŸŽฎ

The following set of options modify the emulation of the Peripheral Interface Adapter chip.

  • -mathpackcontrol bool โ€” enables control of the MATHPACKDISABLE signal thru bit 6 of PIA port B. This function is only required for some dedicated hardware of the author of this program, and should otherwise be left alone. Like, genuinely, hands off. ๐Ÿ™ˆ

๐Ÿง  MMU Options ๐Ÿง 

The following options control the features of the Memory Management Unit. Real talk: for the 800 and 400, no actual MMU chip was used. Instead, the MMU is a set of standard logic gates controlling the memory map of the system. From the 800XL and up, all these gates got integrated into a dedicated hardware chip called the MMU. Regardless of these technicalities, the memory management logic is controlled by the following options:

  • -4kextended bool โ€” enables an additional 4K of memory in the range of 0xc000..0xd000 for the Atari 400 and 800 models. For the XL and XE, this memory region contains parts of the ROM and is never available. For the 400 and 800, this region is otherwise blank. โœจ
  • -axlonram bool โ€” enables emulation of Axlon type RAM expansions, which are controlled by address 0xcfff. These RAM disks have pages of 16K each, mapped into memory from 0x4000 to 0x8000.
  • -axlonbankbits 0..8 โ€” defines the number of bits within the page control port 0xcfff of the Axlon RAM disk emulation used for page selection. The more bits you enable, the more banks are available. Each additional bit doubles the number of 16K banks. Math is math. ๐Ÿ’…
  • -xebankbits 0..8 โ€” this option is only available if the emulator is set up to the 130XE machine type. Then it defines the number of PIA port B RAM bits used to define the selected/active bank. The 130XE uses two bits for selecting the bank, and hence has four pages of 16K, making a total of 64K extended RAM. Now watch this: the more bank bits you enable here, the less compatible the resulting emulation will be to a โ€œstraightโ€ 130XE. Specifically, you lose the proprietary PIA Port B โ€œMathPackDisableโ€ at three bits, the selftest at four bits, the Basic ROM at five bits, separate Antic access at six bits, OS Rom mapping at seven bits, and CPU access control at eight bits. So, like, choose wisely bestie.

๐Ÿ’พ OsROM Options ๐Ÿ’พ

The following options control the emulation of the Operating System ROM and related features โ€” most notably the various Os patches that get installed into it.

NOTE: Original Atari ROM images are not included in the distribution of Atari++ due to copyright restrictions, but Atari++ provides an Os emulation that works just as well in most cases. Also note that the Basic ROM and the Os ROM live in two separate chips, and hence are emulated separately too. ๐Ÿซถ
  • -osapath filename โ€” gives the location of the OS A ROM image. This file contains a simple dump of the memory area 0xd800..0xffff of the original first revision Os of the Atari 800 and 400, or a dump from 0xf800..0xffff for the 5200 console.
  • -osbpath filename โ€” specifies the location of the second revision of the Atari 800 and 400 ROM image file.
  • -os1200path filename โ€” specifies the location of the Atari 1200XL ROM image. This is an early version of the Atari 800XL image with some ROM bugs the emulator has to take care of. ๐Ÿ˜ญ
  • -osxlpath filename โ€” specifies the location of the Atari 800XL and later model ROM image. This ROM image contains the memory areas 0xc000..0xd000, the self-test that can be mirrored to 0x5000..0x5800, and the math-pack and the upper ROM area from 0xd800 to 0xffff, in that order. That's also the natural order within the real ROM chip, which is twice as large as for the former Atari models. ๐ŸŒธ
  • -os5200path filename โ€” specifies the location of the 5200 ROM image.
NOTE: If no ROM image is available, the built-in ROM will be used. This ROM is an XL/XE type of operating system only, and thus requires an 800XL or 130XE machine type for proper emulation.

If none of the above options were given on the command line, then Atari++ will try to locate them itself โ€” or fall back to the built-in ROM if it can't find any ROM at all. So here's what it does: it looks into the directory roms in the current directory. For the XL operating system, it tries to find a file named atarixl.rom in that directory. For the Os A resp. Os B image, files named atariosa.rom resp. atariosb.rom are searched, and loaded if found. ๐Ÿฆ‹

  • -ostype Auto|OsA|OsB|Os1200|OsXL|5200|BuiltIn โ€” defines which kind of ROM shall be loaded into the system. Note that this need not be identical to the type of machine you're emulating, even though that is the default and probably the most useful selection. The 5200 console is the exception: its ROM will not be accepted by anything but the 5200 machine, and any other machine type will not accept the 5200 ROM. That's because the mapping of the hardware differs between the โ€œregularโ€ Atari 8 bit systems and the 5200 console, which makes the ROMs non-portable.

The โ€œbuiltinโ€ option selects the built-in ROM emulation that implements a fully-featured 800XL/130XE ROM. This ROM emulation is used if no other ROM image is found. More on this ROM image in the โ€œOs Emulationโ€ section below.

The โ€œAutoโ€ option, which is the default, does not select a specific ROM โ€” instead it picks a suitable rom image for the selected machine. ๐Ÿ‘‘

  • -installpdevice bool โ€” selects whether a patched P: device handler should be installed that redirects printer output directly to the printer component. If this patch is not installed, printer emulation will be re-routed thru the SIO emulation described below. That works as much as this direct patch does, but it might be somewhat slower. No biggie, just slower. ๐Ÿข
  • -installrdevice bool โ€” bestie, this optionally installs an RS232 interface box handler so serial transfer can happen ๐ŸŽ€. On a real Atari, that handler gets loaded from the interface box by a teeny tiny bootstrap code that's usually part of an AUTORUN.SYS or HANDLERS.SYS file. And yeah, that bootstrapping is emulated too โ€” but the resident handler this option patches in has a glow-up advantage: it doesn't take up any RAM space, unlike the handler that the interface box emulation itself hands you. That said, if a program tries to trick around with the interface box, the bootstrapped 6502-based handler gives you closer emulation than the native emulation this option implements. Otherwise? The native emulation and the 6502 implementation provided by the emulated 850 interface box are functionally identical. Periodt.
Heads up ๐Ÿ’… โ€” this option only installs the CIO emulation layer of the 850 interface box. You still need to enable the interface box itself with the -Enable850 on option. Both, bestie. Both.
  • -installhdevice bool โ€” if you turn this on, the C: cassette handler gets swapped out for an emulator-specific H: (Host) handler that mirrors parts of the host filing system straight into the emulator ๐Ÿฆ‹. Specifically: booting from tape is then not available, and neither is tape access in Basic via the CLOAD and CSAVE statements. RIP to those. The H: device understands all major CIO commands and most XIO commands, following the conventions of DOS 2.0S โ€” so like, RENAME and LOCK XIOs are available by their DOS 2.0S command IDs ๐Ÿ’–. There's a whole dedicated section about the H: device further down, so keep reading.
  • -installedevice bool โ€” this one installs a specific patch that replaces the operating system editor device, E:, and to some degree the keyboard device, K:, with emulator-specific routines that redirect input and output from and to the operating system handler over to standard input and standard output โœจ. So instead of typing into the emulator window, keyboard data is read from standard input, and output to the editor device gets echoed on the console. Bonus: the editor device stream also goes to the front-end of the emulator. Now for the fine print, bestie, because it matters:
This mode relies on the line-buffering of the console and does not provide a full-screen editor, unlike the Atari. You cannot move the cursor back to a previous line and re-enter it. Also, input will not be seen by the emulator until you press RETURN at the end of the line, and only a very limited set of control characters โ€” namely those standardized in ANSI-C โ€” will be transposed from ASCII to ATASCII. For example, cursor movement sequences, which are console-specific, are not available with this patch. ๐Ÿ™ˆ

The major purpose of this patch is to script the emulator, not so much to redirect I/O to a terminal. If redirecting to a terminal is the vibe you want, consider the curses front-end instead ๐Ÿ’œ.

  • -installhasdisk bool โ€” this changes the device letter that the host handler gets installed under ๐ŸŽ€. By default the handler is called H:, but if this flag is set, the handler gets inserted as D: instead, giving you emulated disk access. Programs that entirely access the disk through this handler โ€” BASIC programs, for example โ€” will then run off the host filing system ๐Ÿ”ฅ.
  • -h1dir filename โ€” defines the directory where the first unit of the H: device should be anchored ๐Ÿ“. Files in this directory are accessible through H1: or H:, provided the host handler is patched in by the option above. iykyk.
  • -h2dir filename โ€” specifies the anchor path for the second unit of the H: handler, accessible by H2: โœจ.
  • -h3dir filename โ€” the host directory for the third unit of the H: handler ๐ŸŒธ.
  • -h4dir filename โ€” and finally, the directory for the fourth unit of the host handler ๐Ÿฆ‹. Four units, four dirs, slay.
  • -siopatch bool โ€” if enabled, serial input/output handling gets routed through an OS patch directly to the emulated devices, instead of taking the detour through the POKEY emulation and the emulation of the serial port โšก. This speeds up serial access noticeably โ€” especially disk drive access โ€” but it might cause compatibility problems with some critical software that expects precise timing and exact behavior of the serial hardware. So like, fast, but risky. Choose your fighter ๐Ÿ’….
  • -installmathpatch bool โ€” this optionally installs a series of patches into the MathPack module of the operating system ๐Ÿงฎ. That part of the OS is responsible for floating point support and is used heavily by AtariBasic and other programming languages. This patch replaces the ROM-based math routines with custom patches that make use of the host system FPU instead, hence speeding up any kind of floating point operation dramatically ๐Ÿ”ฅ.
Because of the limited precision of both the Atari floating point model and the host system floating point system, computations performed by the original MathPack might differ slightly from the results you get from the patch. Though ngl, the difference is typically negligible and below the precision of the MathPack itself ๐Ÿ’–.

โœจ KEYBOARD Options โœจ

Ok so these next three options are all about how Atari++ uses your host system keyboard to emulate the Atari keyboard ๐ŸŽน. And lowkey, they currently only influence the emulation of the console keys โ€” which, strictly speaking, are not part of the keyboard hardware of the Atari. Just so we're clear, bestie ๐Ÿ’….

  • -holdoption bool โ€” defines whether the emulator shall emulate pressing the Option</key> key during coldstart. The Atari XL/XE roms query the state of this key during bootstrap and disable the built-in BASIC rom if the Option key is held down ๐Ÿ‘‘. Hence, this option should be set to be able to play (non-BASIC) games on an emulated XL/XE system. Yes, that's the whole trick. You're welcome ๐Ÿซถ.
  • -holdselect bool โ€” defines whether the Select console key shall be pressed during the cold start process. No known OS currently evaluates the state of this key on bootstrap, though. So like... it's there ๐Ÿ’€.
  • -holdstart bool โ€” similar to the above, this enables or disables the activation of the Start console key on coldstart. This signals a boot process from the tape recorder ๐Ÿ“ผ.
  • -bufferkeys bool โ€” Atari++ comes with a smart keyboard type-ahead buffer that lets you type faster than the original Atari hardware is able to react โœจ. Unrecognized keys are buffered until the emulator is able to fetch them. While this feature helps a lot when programming on the emulator, fast gameplay using the keyboard as an input device might become more problematic if keys are delayed rather than swallowed. So like โ€” great for coding, spicy for gaming ๐ŸŽฎ.
  • -keybutton.0.enable bool โ€” this option is only available for the Atari 5200 emulation ๐ŸŽ€. It allows the generation of 5200 "keyboard" events through joystick buttons. If this specific option is enabled, the '0' key on the Atari 5200 keypad can be connected to a joystick button โ€” and similar options exist for all other numeric keys, plus for the hashmark and the asterisk, named keybutton.hashmark.enable and keybutton.asterisk.enable, respectively ๐Ÿ’–.
  • -keybutton.0.button 1..4 โ€” if the above option is enabled, this option controls which of the virtual buttons of a joystick type device is used to trigger the keyboard event for the '0' key on the 5200 keypad ๐Ÿ•น๏ธ. Real talk though: the button numbers required here do not directly relate to the hardware numbering of the OS-specific joystick device โ€” they refer to the button event numbers used by the analog joystick interfaces of Atari++ instead. The First_Button option of this device then defines which hardware button is responsible for generating the virtual button 1 events, and so on.

Similar options exist for the keypad buttons 0 to 9, and for the asterisk and the hashmark, namely as keybutton.hashmark.button and keybutton.asterisk.button โœจ.

  • -keybutton.0.sensitivity 0..32767 โ€” controls the sensitivity of the reaction, i.e. the minimum amplitude of the button input required to trigger the keyboard event ๐Ÿ“. Since buttons are usually digital, this option can be left alone in most cases. Similar options exist for the remaining keypad buttons ๐Ÿ’….
  • -keybutton.0.port devicename โ€” defines the input device for the Atari 5200 keypad '0' button ๐ŸŽฎ. This device is set up in the very same way as for the JOYSTICK emulation, so we refer to that chapter instead. Similar options exist for all other keypad keys ๐Ÿฆ‹.

๐ŸŒˆ CARTRIDGE Options ๐ŸŒˆ

The next set of options lets you insert a cartridge into the emulated cartridge slot of the system ๐Ÿ’พ. Currently, only the left cart slot of the Atari 400 and 800 (respectively, the one and only cart slot of all later models) is emulated. One slot, one destiny, periodt ๐Ÿ‘‘.

  • -cartpath filename โ€” specifies the filename of the cartridge image to load ๐Ÿ“.
  • -carttype
none|8k|16k|32k|oss|ossb|sdx|xegs|bountybob|flash|megarom|atrax

specifies the type of cartridge to load. Unfortunately, the emulator cannot figure out the cart type itself in all cases just by looking at the image file ๐Ÿ˜ญ. Therefore, this option has to be given along with the option above. No shortcuts, bestie.

  • None โ€” a dummy option that just disables the cart, and hence ignores the above option altogether ๐Ÿ™ˆ.
  • 8K โ€” emulates an 8K sized plain cartridge that is mapped into the memory from 0xa000 to 0xbfff โœจ.
  • Right8K โ€” this cartridge type is only available for the Atari800 hardware type and emulates a cartridge for the right cart slot of this system that gets mapped to the area 0x8000 to 0x9fff ๐Ÿ’….
  • 16K โ€” emulates a plain 16K cart occupying the memory region from 0x8000 to 0xbfff ๐ŸŒธ.
  • 32K โ€” emulates 32K cartridges of the 5200 game system ๐ŸŽฎ. This option and the 32K rom images will not be accepted for all other machine types and hence remain unavailable then ๐Ÿšซ.
  • 32KEE16 โ€” emulates a 5200 game system cartridge with a 16K sized image file with incomplete addressing that occupies 32K ROM space ๐Ÿงฉ.
  • Debug32 โ€” emulates a 32K debug cartridge for the 5200 game system with two 16K banks mapped into the area from 0x8000 to 0xbfff ๐Ÿ”ฅ.

Oss emulates an Oss super cartridge that's mirrored into the memory map from 0xa000 to 0xbfff, but internally it's only 16K sized. So it hands you a bank-switching mechanism through the CARTCTRL system component, because internally it's literally two ROM chips โ€” called RomA and RomB from here on out. The lower region 0xa000 to 0xafff is the variable one and can be bank-switched, while the upper region 0xb000 to 0xbfff is hard-wired to the upper part of RomA. Here's the mapping for that lower region, bestie:

  • 0xd500 โ€” RomB Lo
  • 0xd502 or 0xd506 โ€” Blank
  • 0xd501, 0xd503 or 0xd507 โ€” RomA Lo
  • 0xd504 or 0xd509 โ€” RomB Hi
  • 0xd508 and up โ€” disable cart

OssB is also an Oss super-cart, except the cartridge ROM got dumped to disk in a different order, so the addressing of the cartridge ROM contents is different. If the Oss option is giving nothing, try this one instead. no cap.

SDX emulates a 64K large ROM image with eight banks mapped into the region of 0xa000 to 0xbfff.

EXP is a variant of the SDX cartridge with a slightly different bank switching logic. sibling energy.

Diamond is another variant of the SDX cartridge type, with just another bank switching logic.

XEGS emulates a variable size XEGS cartridge. This cart type occupies 16K of memory inside the address space of the 6502 CPU but it's made of several banks that can be mapped into the 0x8000...0x9fff region.

ExtXEGS is a mildly extended version of the XEGS cartridge type that additionally lets you disable the cartridge.

BountyBob emulates the 40K sized BountyBob cartridge for the 5200 games system. This cartridge uses a very unique bank switching mechanism that needs its own emulation, which is exactly what this option provides.

Flash emulates Steven J. Trucker's โ€œAtariMaxโ€ flash ROM cart. It's a 128K or 1MB cart with bank-switching logic mapped into the 0xa000...0xbfff region. This cart type allows flashing, so the cart ROM can genuinely be modified by the emulation process. heads up tho: the emulator will ask you to save back the cart image as soon as the cart shall be removed again.

MegaROM emulates the various types of the Mega ROM cartridges. These carts come in various sizes and map in as 16K banks in the area of 0x8000...0xbfff.

Atrax emulates the 128K bank switching Atrax cartridges that map in as 8K banks in the area of 0xa000...0xbfff.

Will โ€” another super cartridge type, 32K or 64K sized, that maps its 8K sized banks into the area of 0xa000 to 0xbfff.

Phoenix โ€” this type emulates the Phoenix and Blizzard super cartridges. The first is a regular 8K cart that can be disabled, the latter is a 16K switching cart. Both are emulated by the same cart type. two for one, we love to see it.

ATMax โ€” a super cart that comes as 128K or 1MB cartridge.


  • -rtime8 bool โ€” turns emulation of the RTime-8 pass-thru cartridge on or off. This is a cartridge rom containing a battery buffered real-time clock, and it passes the cartridge slot connections thru so you can run the real-time clock together with other cartridges. The default is not to enable the real-time clock cartridge.

๐ŸŽ€ CARTFLASH Options ๐ŸŽ€

The flash cartridge type is the only cart type that can be configured from the command line and the GUI. Currently there's literally just one option available, namely:

  • -enablecartflash โ€” if this option is disabled, the flash cartridge mapping will be disabled on the next reset. But the cart still receives the bank mapping signals, so software can re-enable it. This is useful if you want to re-flash the cartridges with Steve Trucker's flashing software: just disable this switch, insert the flash software disk, and reboot. The cart will be disabled, the Atari will boot from the inserted disk, and the flash software will re-enable the cartridge, letting you overwrite its contents. To write the cart image back to disk, change the cartridge type to โ€œnoneโ€ or insert any other cart. iconic workflow honestly.

โœจ BASIC Options โœจ

These options control the function of the BASIC Rom of the Atari 800XL and later models. Since the Atari 800 and 400 models do not come with a built-in BASIC, these options are ignored for the earlier models; you'd need to insert the BASIC as a regular 8K cartridge for them. Also, whether the basic is mapped for the XL and later series depends on whether the Option console key is held down during bootstrap. That option lives with the keyboard options below, even though it influences how the basic ROM works for the XL and XE series. yes, it's a whole crossover episode.

Atari published three versions of their basic โ€” Revisions A, B and C. Each has its own bugs, with revision B having the most critical bugs (really) and revision C being the most bug-free. On top of that, the emulator also includes a built-in Basic emulation, Basic++, which fixes most bugs of all three revisions.

  • -basicapath filename โ€” specifies the file name of the Revision A Basic rom image, if you have one. The ROM image is a simple 8K memory dump of the ROM appearing between 0xa000 and 0xbfff. Revision A was only available as a cartridge on the 800 and 400 models; if you want to emulate those two models, insert Revision A as cartridge โ€” see the CARTRIDGE section of this manual for details. Revision A contains several bugs and is only of historical interest. museum piece vibes.
  • -basicbpath filename โ€” specifies the file name of a Revision B Basic rom image. This revision shipped with most early 800XL and 600XL machines. It contains one critical bug that crashes the Basic interpreter potentially when entering source code. best avoided, fr fr.
  • -basiccpath filename โ€” selects the location of a Revision C Basic rom image. This revision was delivered with many later 800XL and 600XL models and the last and final XE series. It's the most bug free of the three Basic revisions Atari produced, and the recommended selection if you want an original Basic. the good one.
  • -basictype auto|reva|revb|revc|builtin|disabled โ€” selects the Basic version Atari++ should emulate. The default is โ€œautoโ€, which selects Revision C on XL and XE machines if it is available, otherwise the built-in Basic++.
    • โ€œrevaโ€ selects the revision A Basic, โ€œrevbโ€ the revision B basic and โ€œrevcโ€ the revision C basic.
    • โ€œbuiltinโ€ uses Basic++, which is compiled into the emulator and always available.
    • โ€œdisabledโ€ removes the Basic completely, making it unavailable independently of the state of the Option key on all machine types.

๐ŸŒธ SIO Options ๐ŸŒธ

The Serial Input/Output module is a specific part of the operating system that takes care of serial communication. The Atari++ emulation component of the same name controls the low-level emulation features of all devices emulated on the serial port โ€” so that's the disk-drives, the printer, the 850 serial interface box and the tape. The emulation of the serial port can be bypassed with the -siopatch option described in the OS Option section above, giving a noticeable speedup for disk-drive and printer, but possibly also causing compatibility problems for software that depends on precise timing or side-effects of the Os implementation. You usually need not care about the settings below, since they closely match those of typical serial hardware anyhow. set it and forget it.

  • -serincmddelay 0..240 โ€” the amount of time taken by a serial device to accept a command frame. This time is given in horizontal blanks. Defaults to 50 lines.
  • -readdonedelay 0..240 โ€” the time taken for a serial read command to complete. For the disk-drive emulation, this would emulate the time required to read a sector from disk up to the time where the first byte of the sector arrives at the port. This setting also defaults to 50 lines.
  • -writedonedelay 0..240 โ€” required time to complete a write command. For the disk-drive, this is the time taken from the last byte of a sector arriving at the drive up to the time where the disk-drive sends the acknowledgement frame. This setting defaults again to 50 lines.
  • -formatdonedelay 0..1024 โ€” required time to format a disk in a disk-drive, measured as the time from issuing the command up to the time where the first byte of the sector status map arrives at the serial input. This is again given in horizontal lines. Since the Os assumes that the timing of formatting is a bit more relaxed than the regular reading time โ€” yes, formatting is a read command for the Atari โ€” this is a separate option, defaulting to 400 horizontal lines.

๐Ÿ’… PRINTER Options ๐Ÿ’…

This option set controls the printer emulation. Commands and data enter this emulation either by the SIO, or directly by the P: handler should it be patched into the Os. See the OS Options for more details on this. This option set is used in either case, no matter how the emulated printer is accessed. one config to rule them all.

  • -printtarget tospoolcommand|tofile โ€” selects where printer output is sent to. For the tospoolcommand selection, printer output is piped into the printcommand selected by the option below. This is typically the โ€œlprโ€ or โ€œlpโ€ command on Unixoid systems. For tofile, printer output is sent to a regular file. On some systems, this might be the only available option to print at all.
  • -printcommand file โ€” specifies the command used to print out text on the host system. The text arriving at the emulated printer will wait in a queue and will be flushed regularly, appearing at the STDIN of this command. Typically, this should be either lpr or lp, depending on the printing system you use at your machine.
  • -printfile filename โ€” specifies the file printer output is sent to, should this type of output be selected. This is by default empty, disabling printer output completely, though the printer appears to be turned on. fake it till you make it ๐ŸŽ€
  • -appendtoprintfile bool โ€” tells the emulator whether the printer output file you picked in the option right before this one gets completely yeeted and rewritten every single time the printer spits something out, or whether the new stuff just gets tacked onto the end like a group chat you never leave. Default vibe: new output overwrites the old printer dumps, no mercy. ๐Ÿ’…
  • -enableprinter bool โ€” turns the emulated printer on or off. Set it to off and the printer will literally not react to any SIO commands, like it's been unplugged and is just lying there. Otherwise, printing is allowed. ๐Ÿ–จ๏ธโœจ
  • -transposeeol bool โ€” okay so this one is lowkey important. The Atari does not use the regular LF character to separate lines in printer output. Instead it uses the character 0x9B (that's CSI in the ANSI set, and it's named EOL on Ataris) as its line separator. So for printing text, EOL has to be transposed into line feeds by this option โ€” which, btw, is also the default. BUT for graphics output, this character transposition will change the meaning of the graphics data sent to the printer, which means it will distort the graphics. ๐Ÿ˜ญ
NOTE: Currently, Atari++ does not include the emulation of a graphics printer. All control and graphics sequences sent out to the emulated printer will be spooled directly into the print command without interpreting them further.
  • -flushdelay 0..60 โ€” this is the delay, in seconds, from the last bit of data arriving at the emulated printer until all the collected text/graphics actually get printed out. So if data comes in slower than this delay, it'll show up in separate spool jobs. Defaults to five seconds. โณ

๐ŸŒˆ SPEED Options ๐ŸŒˆ

The following set of options controls the timing of the emulator. Several other factors influence the maximum speed though, bestie, so let's be real about them:

  • First of all, the graphical front-end of the emulator might be more or less performing. For full-screen emulation, the SDL front-end is performing well provided no pixel upscaling is used. In all other cases, the X11 frontend offers higher speed. This is not the fault of the emulator, it's just the poor performance of SDL being SDL. ๐Ÿ’€
  • Furthermore, the sound emulation has some impact as well. For software speech emulation, high sampling rates and slim buffers are a must, which causes additional software overhead and higher CPU loads.

To maximize the speed, either run the X11 frontend on 1x1 or 1x2 pixel sizes and reduce the quality of the audio output. ๐Ÿ”ฅ

  • -unlockrate bool โ€” set this to true and you can pick a custom, non-standard frame rate that is not locked to the video mode (see below) of the emulated machine. Default is to disable this option, which locks the frame rate to the natural frame rate of the emulated machine. ๐Ÿ”“
  • -framerate 1..100 โ€” this specifies the screen refresh rate, given in milliseconds per frame. A standard PAL screen with 50 frames per second needs 20 milliseconds per frame; an NTSC screen needs 17 milliseconds. Defaults to 20, i.e. the PAL rate โ€” but it's ignored unless the frame rate is unlocked with the unlockrate switch above. โฑ๏ธ
  • -maxmiss 1..16 โ€” unlike the above, this one controls how many frames the emulator may miss to keep the emulation speed. Set it to 1 and the emulator never misses a frame โ€” which may make it slow on less performing systems. Set it higher than one and at most that many frames might be dropped to keep up the refresh rate set by the option above. So it doesn't hurt to pick a higher maxmiss on a fast machine, and it'll keep up the speed for more complex graphics on slower machines too โ€” at the cost of not emulating the video output as frequently. ๐Ÿƒโ€โ™€๏ธ
  • -videodmode PAL|NTSC โ€” intentionally identical to the same option of the ANTIC and GTIA emulation, this selects the frame rate based on the video output mode. For a PAL machine, it selects a freshmode of 50 frames/second; for a NTSC machine, the emulator will try to generate 60 frames/second. This option is overridden if the unlockrate switch above is enabled. ๐Ÿ“บ

๐Ÿ’พ DISKDRIVE Options ๐Ÿ’พ

The following set of options controls the emulation of up to four disk drives. The diskdrive options consist of a base name, a dot, and the unit number specifying the unit of the disk drive they control. So yes, all the following options exist four times, and just differ by the digit behind the dot. Slay. ๐ŸŽ€

  • -enable.1 bool โ€” enables or disables the first diskdrive. Set it to off and the first drive won't react, as if it's been turned off; otherwise it's turned on. Default is to enable the first drive and disable all the others. ๐Ÿ‘‘
  • -image.1 filename โ€” specifies the path to an image file to load into the drive. The Atari++ emulator supports several kinds of image files, so let's go through them one by one, no skipping:
    1. Raw disk images that keep the contents of the disk sector by sector. These files are typically identified by their extender .xfd.
    2. The .atr format, implemented by several other Atari emulators. It consists of a tiny header describing the format and the size of the disk, plus the sector image.
    3. Atari binary load files, or for short, so-called .exe files. These consist of a two 0xff byte header plus address information telling where to place the data to load. These files are booted by writing them as DOS 2.0S files onto disk, together with a minimal game DOS header that bootstraps the .exe format. Note that no full DOS will be available for these files, though this emulation is sufficient for most .exe based games right away.
    4. The .atx format โ€” because while the above formats capture all high-level details of disks, they don't include enough info to reproduce the low-level behavior of the disk drive. Specifically, copy protected disks cannot be represented by them. Atari++ supports .atx for that, which includes pecularities such as disk timing, duplicate sectors or sector defects. Again, the emulator cannot create such disk images, but it is able to read from them. ๐Ÿ•ต๏ธโ€โ™€๏ธ
    5. .dcm images, prepared by the โ€œDisk Communicatorโ€ program, and they're (slightly) compressed. Similar to the .exe files, Atari++ cannot re-compress these. Therefore, disk images of this type are marked write-protected, making writes to these disks fail. ๐Ÿšซ
    6. All of the above disk image types can be compressed by means of the gzip program; Atari++ will then uncompress them on demand as soon as the image gets loaded. Since it does not re-compress images, these disks also always end up write-protected.
    7. Last but not least, .bas files, which are tokenized Basic files. To load such files, make sure that either a Basic cartridge is inserted, or the Basic emulation is enabled. The Basic program will not boot automatically if the emulated machine is reset โ€” unless Basic++, i.e. the built-in Basic dialect, is selected and the Basic file is inserted into the first drive. All other Basic dialects will see the basic image as a file named AUTORUN.BAS on a write-protected disk. To start the file, enter the command
RUN "D:AUTORUN.BAS"

manually on the editor window of the emulated Basic and press RETURN. ๐Ÿซถ

  • -protect.1 bool โ€” enables or disables the write-protection of the inserted disk. Set it to on and the disk image gets write-protected as if the write-protection notch has been covered on a physical disk. The emulator also write-protects disk images automatically if:
    • the corresponding image is marked non-writeable by the protection bits of the host operating system, or
    • the disk is built up for the .exe binary load file emulation, or
    • it comes in the already compressed .dcm Disk Communicator format.

Similarly, all .gz compressed images and .bas files are write-protected, no matter what the original file format has been. ๐Ÿ”’

  • -drivemodel.1 1050|810|815|happy1050|warpspeed810|speedy|xf551|usturbo|indusgt โ€” selects the drive model to emulate. Let's break it down:
    • The 1050 is the disk drive that shipped with the XL series of computers, and it's the default selection. It handles single or extended density disks of 720 or 1040 sectors, each of which is 128 bytes long. Note that this drive type does not support ATR or XFD images with sector counts or sector sizes that go beyond the capabilities of this drive.
    • The 810 is the first disk drive available for the 800 and 400 models. It handles only single density disks, i.e. disks of 720 sectors of 128 bytes each. All other disk types will not be accepted.
    • The 815 drive is a dual-disk drive supporting single or double density disks of 720 sectors, either 128 or 256 bytes per sector.
    • The xf551 is the last floppy drive sold by Atari; it allows single, extended, double and quadrupel density disks. It has two heads and can read the disk from both sides simultaneously.
    • All other drive types โ€” happy1050, warpspeed810, speedy, usturbo, indusgt โ€” are third party extensions that allow higher transfer speeds and extended sector formats.

Note that the file management system that's part of the built-in OS emulation does not make use of the higher serial transfer speeds of these extensions, but third-party file systems will be able to detect these drive types and will then switch to a higher transfer speed. โšก

Similar disk drive options exist for drives two to four by replacing the digit 1 in the above list by the appropriate drive number. ๐Ÿฆ‹


๐Ÿ”Œ SIOCABLE Options ๐Ÿ”Œ

The following set of options control the overall setup of Matthias Reichl's โ€œAtariSIOโ€ emulation. It requires that the kernel interface and development files for /dev/atarsio are available. Alternatively, the DirectSerial can be used, which might be less reliable since it cannot ensure correct timing.

To make use of the AtariSIO emulation, connect your Atari drive by means of one of two possible interface cable types to the PC, and disable the built-in disk drive emulation for the corresponding drive unit. I.e. if your external drive has been set to drive unit 1, the internal emulation for drive 1 has to be disabled by

-enable.1 false

, or de-selecting the corresponding gadget in the DiskDrive menu. ๐Ÿ’œ

  • -cabletype 1050-2-PC|ProSystem โ€” ok so this one picks which cable you wired a 1050 or 810 drive up to your PC with ๐Ÿ’…. rn AtariSIO supports exactly two layouts, the 1050-2-PC and the ProSystem one. that's the whole menu bestie, no secret third option ๐Ÿ™ˆ
  • -enableatarisio bool โ€” the big on/off switch for the whole AtariSIO interface, no matter which protocol is doing the talking. it's giving master switch energy ๐Ÿ”ฅ
  • -directserial bool โ€” if you turn this on, Atari++ skips the AtariSIO kernel interface and uses a user space interface instead, so you don't have to install the AtariSIO kernel module at all ๐ŸŽ€. sounds cute right? but ngl, timing can't be as precise as the kernel interface, and this interface may fail if the system is under heavy load ๐Ÿ˜ญ. also, if AtariSIO isn't compiled into your system, this is the only possible interface method anyway โ€” and in that case this command line option doesn't even appear, because direct serial communication is then always enabled. periodt.
  • -cmdtodatadelay 0..2000 โ€” only used when directserial is enabled, and it's a timing detail for the Atari SIO emulation โœจ. specifically: the delay from the start of the falling edge of the COMMAND line to the start of the first byte of the command frame, given in micro seconds. per the Atari SIO specs this delay shall be between 750 and 1600 usecs long. the default is 900usecs ๐Ÿฆ‹
  • -cmdframelength 800..10000 โ€” another timing constraint of the Atari SIO directserial communications protocol, bestie: the total length of a command frame, measured from the falling to the raising edge of the COMMAND line, again in micro seconds. per the Atari SIO specs this delay shall be between 4060 and 5210usecs long, and the default here is 5150usecs ๐Ÿ’œ. heads up though โ€” because of the load on your host system, you might need to fine-tune this parameter to get a stable SIO communication ๐Ÿ˜ญ

๐ŸŒธ TAPE Options ๐ŸŒธ

ok so besides disk drives, Atari++ also supports an archaic medium for data storage: the 410 and 1010 tape drives ๐ŸŽ€. they store binary data in frequency-modulated form โ€” a high tone for a one, called โ€œmarkโ€, and a somewhat lower tone for a zero, also called โ€œspaceโ€ โœจ.

the emulator supports two types of tape images:

  • .cas files โ€” tape archives that have already been converted into a binary representation ๐Ÿฆ‹
  • .wav files โ€” which contain the digitized audio from the tapes directly ๐ŸŽต

for the .wav ones, Atari++ emulates the analog filters required to decode the audio, but ngl, due to the nature of the process, .wav files are less reliable, similar to real-world tape recordings ๐Ÿ’€. if possible, use .cas files whenever possible. that's the move ๐Ÿ’…

the option

  • -image filename โ€” defines the .cas or .wav file to be read from or to be written to ๐Ÿซถ. Atari++ accepts both the cas or wav format as input, and can create both file types when writing to a simulated tape. the emulator cannot append to tape archives, i.e. each recording has to go into a separate file ๐Ÿ˜ญ
  • -play bool โ€” this presses the โ€œplayโ€ button of the simulated tape drive, and hence allows the motor to spin if enabled by the main system โœจ. as a command line option it doesn't make much sense, lowkey โ€” it's best used within the emulator ๐Ÿ’…. the flow is: once the Atari operating system beeps once, requesting you to start the tape, enter the menu and start the tape by the button of the same name in the Tape menu, then return to the emulation and press the RETURN button there. this will start the playback ๐ŸŽ€
  • -record bool โ€” for recording data on tape, the Atari operating system beeps twice, requesting you to press the โ€œplayโ€ and โ€œrecordโ€ buttons ๐ŸŽ™๏ธ. same must be done in the emulator: go to the menu, into the Tape menu, enable the โ€œplayโ€ option there, but also select the โ€œrecordโ€ button below. the corresponding command line option is as given above, but it also makes little sense as a stand-alone option ๐Ÿ™ˆ. afterwards, return to the emulator window and press RETURN. this starts the recording process ๐ŸŽ€. and if the โ€œsiosoundโ€ option is enabled, you should hear a distinct high pitch tone โ€” that's the classic sound of data recordings on tape ๐Ÿ”Š
  • -eject bool โ€” presses the simulated eject button of the tape drive, removing the recording from the drive ๐Ÿ’ซ. this unloads the image and completes it on disk. it's most useful as a button of the same name in the Tape menu as well ๐Ÿซถ
  • -recordaswav bool โ€” controls the output format when recording data on tape ๐ŸŽ€. by default, Atari++ records in the more robust .cas format, which doesn't require additional decoding โœจ. if this option is set, the emulator creates .wav files that correspond to the audio information that would be recorded on a real tape. this format is not recommended for archiving purposes โ€” it creates longer files that are also harder to decode ๐Ÿ’€

the following additional options are also recognized by the tape subsystem:

  • -videomode PAL|NTSC โ€” defines the video mode the system operates in, and by that the timing of the tape ๐ŸŒˆ. this should be, and on the command line only can be, set identical to the video mode of the host system ๐Ÿ‘‘
  • -motoroffeofgap 20..10000 โ€” controls when the emulator considers a stopping tape as the end of the recording ๐ŸŽ€. unlike the real machine, where the tape is entirely controlled by the user, the emulator has to make some guessing as to when a recording should be considered as completed, and no additional data is following ๐Ÿ˜…. it currently does this whenever the motor stops longer than the indicated time, in milliseconds. the value defaults to 3000, i.e. three seconds โฑ๏ธ. once the motor halts longer than this, the simulated tape is removed from the tape recorder and no further data is expected. enlarge this value if a tape file is created by a relatively slow BASIC program ๐Ÿข

๐Ÿ’œ ATARISIO Options ๐Ÿ’œ

this option group fine tunes the AtariSIO interface whenever it's available โœจ. unlike the SIOCABLE option group, this set exists once per external drive and defines parameters that are specific for the drive and not for the cable interfacing to the drive ๐ŸŽ€. therefore, the following options exist four times, where the suffix โ€œ.1โ€ needs to be replaced by the appropriate drive number ๐Ÿ’…

  • -sioenable.1 bool โ€” enables the first external drive โ€” or subsequent ones for higher suffixes ๐Ÿฆ‹. it is disabled by default. note that for redirecting drive accesses to AtariSIO, the emulator-internal drive emulation must be disabled as well. hence, to use a real 1050 as first floppy drive, the following two options would be required:
-sioenable.1 true -enable.1 false
  • -sioprotect.1 bool โ€” enables or disables an additional write-protection that blocks any write access to the external drive, as if the floppy write-protection notch has been covered ๐Ÿ”’. this option defaults to off ๐ŸŽ€
  • -siotimeout 1..30 โ€” specifies the timeout in seconds that applies to regular commands โณ. since the Atari++ emulation of the diskdrive applies at the level of raw POKEY communcations, the emulator cannot know the desired timeout that has been selected by the driving Atari software ๐Ÿ˜…. this timeout defaults to seven seconds โœจ
  • -sioformattimeout 10..120 โ€” specifies the timeout in seconds for formatting commands, which typically require longer than regular commands ๐Ÿ’ซ. this timeout defaults to sixty seconds, i.e. one minute, but is overridden by the specifications that are returned by the disk drive itself as soon as a status command is send to the drive ๐Ÿ‘‘

๐Ÿ•น๏ธ JOYSTICK Options ๐Ÿ•น๏ธ

Joystick emulation for Atari++ consists of two layers bestie ๐ŸŽ€:

  1. the emulation of the corresponding port at the emulated hardware, and
  2. the generation of sigals to feed data into this emulated port.

for that, Atari++ uses the concept of a generic input device consisting of two axes and four buttons, abstracting from the real physical device on your machine to generate the input โœจ. for a physical (analog) PC joystick, the meaning of the two axis and four buttons should be obvious, but other sources for the abstract input device exist as well โ€” e.g. the mouse or the keyboard ๐ŸญโŒจ๏ธ

later stages of the Atari++ input layer then only refer to the buttons of these virtual devices, e.g. the keypad options of the 5200 device ๐Ÿ’…

the following set of options do not control the physical input devices, but rather select how the emulator should make use of this abstraction layer, whereever it comes from, to form digital joystick input ๐ŸŽฎ. i.e., these options control the emulation of the emulated joystick port on input from an abstract input device ๐Ÿ‘‘

similar to the diskdrive options, all joystick options exist four times, now numbered from zero to three ๐Ÿฆ‹. the digit behind the dot in the option name defines the joystick port this option controls. for the Atari 800 and 400, all four ports are used by the emulator; for the XL and later models, only the ports 0 and 1 are mapped to the emulated hardware, similar to their physical counterparts โœจ

  • -joystick.0.sensitivity 0..32767 โ€” this option sets a threshold that must be crossed by the abstract analogue joystick input to detect a joystick movement on the emulated joystick port ๐Ÿ’ซ. the lower the number, the higher the sensitivity. the abstract input devices generate axis movements from -32767 to 32767, and the default of this option is that a movement of 8192 units on this scale is required to generate an input signal ๐ŸŽ€
  • -joystick.0.port devicename โ€” defines the name of the abstract device that should be connected to the port ๐Ÿ”Œ. currently, the following devices exist:

๐Ÿฆ‹ MouseStick.0

uses the mouse on your host system as abstract input device, with the horizontal and vertical position of the mouse pointer forming the horizontal and vertical axis of the abstract input device connected to the port ๐Ÿญโœจ. there is only unit 0 of this device ๐Ÿ’…

๐ŸŽฎ RelMouseStick.0

Basically the same vibe as the MouseStick device above, except it vibes off mouse movements instead of the absolute mouse coordinate. This is often the better alternative, ngl โ€” unless your host machine's pointer device is also absolute-positioned, i.e. a trackpad or a touchscreen. ๐Ÿ–ฑ๏ธโœจ

๐ŸŽฎ KeypadStick.0

Takes the keypad on the host system's keyboard and turns it into the abstract input device. Digits 8, 4, 6 and 2 generate maximal axis movements in top, left, right and down movement, respectively; keys 7, 9, 1 and 3 move in the corresponding diagonal directions. The 0 and Enter map to button 0 of the joystick. And there is โ€” quite obviously โ€” only unit 0 of the keypad-stick. These keys can be reconfigured dynamically, and its config lives under the KeypadStick section below. โŒจ๏ธ๐Ÿ’…

๐ŸŽฎ AnalogJoystick.0

Uses the (real) analog joystick connected to the port controlled by the /dev/js0 device to form the abstract input of the device. Which physical axis forms which abstract axis is controlled by the analog joystick options described below, but the default mapping is the obvious one: each physical axis maps to the same abstract axis, and buttons 0 and 1 map to their abstract counterparts. Atari++ accepts up to eight physical joysticks by replacing the digit 0 in the above option by 1 to 7 for further joysticks that are then connected to the corresponding joystick devices. ๐Ÿ•น๏ธ

๐ŸŽฎ DigitalJoystick.0

Uses a (real, antique) Atari Joystick connected to an analog PC joystick port by means of the โ€œEl Cheapoโ€ joystick adapter of the author. This adaptor maps the digital input lines of a digital joystick to the buttons 1 to 4 of an analog joystick, and maps the one and only button by a resistor array to axis 0. As above, some parameters of this interface can be setup by the digital joystick options described below. Similar to above, the signals generated by this hardware are then read thru the standard /dev/js0 Linux interface, and up to eight digital joysticks can be emulated this way, accessing the devices /dev/js1 to /dev/js7. NOTE: You need to build some additional hardware to make use of this abstract device, but you get perfect Atari feeling as a bonus. ๐Ÿ”ฅ

The schematics for this interface are included in the distribution as โ€œjoystick.psโ€. ๐Ÿ“

๐ŸŽฎ SDLAnalog.0

Similar to โ€œAnalogJoystick.0โ€ except that the joystick position isn't read from the kernel interface directly, but rather indirectly thru the SDL library. This makes absolutely no difference except that on some systems only the kernel interface is available, whereas on others only the SDL interface can be used. ๐ŸŒˆ

๐ŸŽฎ SDLDigital.0

Works exactly the same as โ€œDigitalJoystick.0โ€ except that the joystick movements are reported thru the SDL library rather than thru the kernel interface. Causes no difference in usage and options otherwise. โœจ

๐ŸŽฎ None

Do not connect any device to this joystick input and read it as โ€œcentered, no button pressedโ€ all the time. ๐Ÿ’ค


Similar to the diskdrive options, the joystick options exist four times with the unit numbers 0 to 3. The default for the abstract input device is to use the keypad stick for joystick zero and leave all other joysticks and paddles unconnected.

NOTE: The 5200 console system does <b>not</b> use standard Atari digital joystick input. Instead, analog joysticks connected to the paddle inputs are used. It is therefore <b>mandatory</b> to define the input devices of the first two paddles, paddle 0 and 1, to have an input device for the 5200 console. The digital joystick inputs defined by the options above WILL NOT WORK. ๐Ÿ’€

๐Ÿ•น๏ธ PADDLE Options

The following set of options control the emulation of up to eight paddles that can be connected to the emulator. Similar to the above, the emulation requires an abstract input device to read the input of the emulated paddle from; paddle emulation uses only axis zero of this abstract device to form the paddle input, but requires buttons zero and one for the emulation of the two paddle buttons. ๐ŸŽ›๏ธ

NOTE: The paddles on the Atari machines use the joystick input lines for the paddle buttons. For that reason, paddles and joysticks <b>should not</b> make use of the same input device. ๐Ÿ™ˆ
NOTE: For the 5200 system, the controller is connected as a paddle and hence <b>these</b> โ€” and not the joystick options โ€” must be defined. ๐Ÿ‘‘

As above, the following options exist several times, with the digit 0 replaced by 1..7 for all other paddle units. Whereas the Atari 800 and 400 allow this maximal number of eight paddles, inputs 4 to 7 are not available on a real Atari XL or XE. However, the Atari++ allows connection to these paddle inputs regardless of the emulated host input as the corresponding input lines are otherwise unused on the real hardware either. ๐ŸŒธ

  • -paddle.0.sensitivity 0..32767 โ€” Adjusts the sensitivity of the paddle and hence the movement necessary for a full paddle rotation. Note that the abstract input device generate movements on a scale of -32767 to 32767. ๐ŸŽš๏ธ
  • -paddle.0.invert bool โ€” Since paddle input has no natural orientation, this option allows you to invert the meaning of the input device position. Since some games interpret paddle positions just opposide to others, this flag helps you out as it changes left movement to right, or upwards movement to downwards movement. ๐Ÿ”„
  • -paddle.0.port devicename โ€” Defines which abstract input device to use to feed the paddle emulation. The very same devices as for the joystick emulation are available here, though pure digital devices as the keyboard or the digital joystick device are not very usable for paddle emulation. Since an abstract input device provides two axis and two buttons each, it makes sense to map one input device to two paddle inputs: for that reason, each even paddle number maps to the first axis and the first button, and each odd paddle number maps to the second axis and button of each abstract input device. ๐Ÿ’…

โœ๏ธ LIGHTPEN Options

Atari++ also allows emulation of the lightpen as a kind of analog input device. Though rarely used, the corresponding input lines at ANTIC are available and can be feed by this emulation component. There is only one lightpen device available, though its other options are very similar to the paddle emulation. ๐ŸŒŸ

  • -lightpen.sensitivity 0..32767 โ€” Defines the sensitivity of the lightpen and hence the factor/adjustment between the real physical device and the emulated position of the lightpen on the screen. ๐Ÿ“
  • -lightpen.port devicename โ€” Specifies which abstract input device to connect the emulated lightpen to. The list of available devices is identical to the list of devices for all other gameport like input, please see the JOYSTICK Options section above. ๐Ÿ–Š๏ธ

โŒจ๏ธ KEYPADSTICK Options

Options in this group define the keys used by the Keyboard Joystick emulation. By default, the numeric keypad to the right of a standard PC keyboard is used for this purpose, but the keys can be reconfigured. ๐ŸŽนโœจ

  • -leftup keyname โ€” defines the key that moves the stick in the diagonal left upwards position. Pressing the left and the up key simultaneously is equivalent to this. Key names are either the numbers 0 to 9 or the letters A to Z, indicating the corresponding keys on the main keyboard, or are taken from the list below. An empty string indicated by an empty pair of opening and closing quotes disables the corresponding function. ๐Ÿฆ‹
  • -up keyname
  • -rightup keyname
  • -left keyname
  • -right keyname
  • -leftdown keyname
  • -down keyname
  • -rightdown keyname โ€” move all the joystick in the corresponding direction. Diagonal directions can be either assigned to separate keys, or are reached by pressing the two direction keys simultaneously. ๐ŸŒˆ
  • -center keyname โ€” centers the joystick. ๐ŸŽฏ

The option

  • -leftbutton keyname โ€” configures the key that emulates the left button if the keypad is used as a paddle, or the one and only button if the keypad emulates a digital joystick. ๐Ÿ’–
  • -rightbutton keyname โ€” selects the key to emulate the right button on paddles. The key has no function if the keypad emulates a standard Atari joystick. ๐Ÿ‘‘

Key Names are either alpha-numeric characters from 0 to 9 or A to Z indicating the corresponding keys on the main keyboard, or the following special names. Note that names containing spaces need to be quoted on the command line:

  • Cursor Left โ€” Left pointing arrow of the four cursor keys
  • Cursor Right โ€” Move cursor right key
  • Cursor Up โ€” Move cursor up
  • Cursor Down โ€” Move cursor down, all the above on the cursor keypad
  • Return โ€” Return key on the main keyboard
  • Tab โ€” TAB key on the main keyboard
  • Backspace โ€” Backspace key on the main keyboard
  • Keypad 0 โ€” Digit 0 on the numeric keypad, similar for 1 to 9
  • Keypad Divide โ€” Division key on the numeric keypad
  • Keypad Multiply โ€” Multiplication key on the numeric keypad
  • Keypad Plus โ€” Addition on the numeric keypad
  • Keypad Minus โ€” Subtraction on the numeric keypad
  • Keypad Dot โ€” Decimal separator, dot or comma, on the keypad
  • Insert โ€” The insert key between main keyboard and numeric pad
  • Delete โ€” The delete key in the same group
  • Home โ€” The home key
  • End โ€” The end key
  • Scroll Up โ€” The page up key
  • Scroll Down โ€” The page down key

๐ŸŽฎ ANALOGJOYSTICK Options

Unlike the JOYSTICK Options, the following set of options describes the mapping of a true analog joystick connected to one of the joystick device drivers to the abstract input device that forms the basis for either joystick, paddle or lightpen input. Hence, it defines the layout of the AnalogJoystick devices that can be connected to the above emulation components. ๐Ÿ•น๏ธ๐Ÿ’ซ

Okay bestie, continuing right where we left off โ€” the digit-swap situation ๐Ÿ’ซ


Similar to basically all the options above, these ones show up several times, once per device, with the digit 0 swapped out for the unit number of the device it belongs to. So the analog PC joystick sitting on /dev/js1 gets set up with options just like the ones below, except a 1 takes the place of the 0. Slay, consistent naming โœจ

  • -first_button 1..16 โ€” tells the emulator which physical joystick button should map onto button zero of the abstract input device. Default? The first physical button goes to the first button, aka button zero, of the abstract device. So it defaults to button #1 of the real device. And here's the twisty part if you're rolling with the 5200 keypad device (that's the KeyButton.0.Button family of options): the button index #1 you use in the keyboard config points at whatever button this option picked, not straight at a hardware button. So keypad buttons get routed twice โ€” first stage goes through the hardware abstraction layer set up by this option, and the second stage is the keyboard device picking one of the four abstract buttons that layer offers. Nested. Iykyk ๐Ÿงš
  • -second_button 1..16 โ€” same energy as above, but this one picks the real button that hooks up to the emulated second button of the emulated device.
  • -third_button 1..16 โ€” again with the routing: one hardware button โ†’ one virtual button on the hardware interface layer. But heads up, bestie, because the Atari hardware can only really handle at most two buttons, namely for the paddles. So the third and fourth buttons are only usable for the 5200 keypad emulation โ€” go check the keyboard configuration chapter for the deets ๐Ÿ’…
  • -fourth_button 1..16 โ€” the input line of the fourth button that an abstract joystick device might support. Once again: only usable from the keypad emulation. Periodt.
  • -haxis.0 xaxis.1|yaxis.1|xaxis.2|yaxis.2 โ€” says which axis of the physical joystick emulates the horizontal axis of the abstract analog joystick device. The default is the first horizontal axis of the physical joystick. Easy.
  • -vaxis.0 xaxis.1|yaxis.1|xaxis.2|yaxis.2 โ€” same thing but for the vertical axis of the abstract device. And the default is, of course, the first vertical axis. Obviously ๐Ÿ’–

โœจ SDLANALOG Options โœจ

This is a modified AnalogJoystick interface that reads joystick positions thru the SDL library instead of hitting the kernel interface directly. Its config options are identical to the AnalogJoystick interface's options, so we are not describing them all over again here. Go read the other list, bestie ๐Ÿฆ‹

๐ŸŽ€ DIGITALJOYSTICK Options ๐ŸŽ€

Next up: the options for setting up the digital joystick input and the "El Cheapo" Joystick input adapter โ€” that's the little thing you can use to connect a true Atari digital joystick to the analog gameport input of the PC. This set also exists several times, once for every available gameport detected on the host system. And once again: replace that digit 0 with the unit number of the device your joystick is plugged into ๐Ÿ‘‘

  • -upbutton.0 Button.1|Button.2|Button.3|Button.3 โ€” defines which of the four joystick buttons on the analog gameport acts as the input for the upwards movement line. The default is button three.
  • -downbutton.0 Button.1|Button.2|Button.3|Button.3 โ€” same deal for downwards movement. The default is button one.
  • -leftbutton.0 Button.1|Button.2|Button.3|Button.3 โ€” picks the button that acts as the left movement input. This defaults to button four.
  • -rightbutton.0 Button.1|Button.2|Button.3|Button.3 โ€” picks the button for right movement input. The default is button two.
  • -triggeraxis.0 XAxis.1|YAxis.1|XAxis.2|YAxis.2 โ€” selects the analog gameport axis that reads the digital joystick button input. The default is that the digital fire button is connected to the first horizontal axis.
  • -triggerthres.0 -32768..32768 โ€” so here's the tea ๐Ÿต: because the digital button gets read by the game port as an analog input, the digital signal arrives as a numerical value between -32768 and 32767 at the digital joystick device of the emulator. This option sets the threshold at which the button counts as pressed vs. released. The exact values totally depend on the resistance network wired to that analog gameport line, but the default of 16384 works fine for the author's hand-soldered adaptor. Hand-soldered?! Iconic ๐Ÿ”ฅ
  • -inverttrigger.0 bool โ€” this switch flips the fire button input line reading, so active inputs read as released fire buttons and vice versa. Shouldn't be necessary with the author's interface, so the default is off. Don't touch it unless you gotta.

๐ŸŒˆ SDLDIGITAL Options ๐ŸŒˆ

This is just a slightly modified DigitalJoystick interface that connects to SDL instead of the kernel interface. All its options are identical, so please refer to the list right above for the details. Nothing new under the sun, bestie ๐Ÿ’œ

๐Ÿ‘‘ OSSHQSOUND Options ๐Ÿ‘‘

Alright, time for audio ๐ŸŽง. Here's a set of options to control audio generation thru the OSS HQ driver, which makes use of the Open Sound System kernel interface or an equivalent emulation โ€” ALSA, for example. Different from the POKEY Options, these options are about the quality of the samples generated by the POKEY emulation and how they're built up for OSS. For audio output to actually work, you need an Open Sound System compatible audio driver available, and you need permission to access the /dev/dsp device. No permission, no vibes ๐Ÿ˜ญ

Heads up, bestie: generating audio samples at high quality has a non-neglectable impact on CPU load. If your machine can't keep up with the natural framerate, or the CPU load is just too high, try lowering these settings, use a different audio front-end, or disable sound output alltogether. Your CPU will thank you ๐Ÿซถ
  • -enablesound bool โ€” turns generation of audio output on or off. The default is to enable audio generation, unless no audio output device is available โ€” in which case audio output gets disabled.
  • -enableconsolespeaker bool โ€” enables or disables emulation of the Atari console speaker. The Atari Os uses this speaker for keyboard click sounds and the buzzer, and some games even use the console speaker for speech output. Cute.
  • -consolespeakervolume 0..64 โ€” sets the output volume of the console speaker. Setting it to zero effectively disables the output, and setting it higher than 32 may cause distortion with regular POKEY audio output. The range goes from zero up to 64 for maximal volume, with the default being 32. Stay in your lane at 32, ngl.
  • -audiodevice filename โ€” names the audio device to send the samples to. This device must accept all Oss specific ioct() settings. It defaults, naturally, to /dev/dsp.
  • -samplefreq 4000..48000 โ€” the sampling frequency in Hz at which samples get generated, which is also the limiting frequency for the audio signals. Higher value = higher frequencies can be emulated = more natural the sound plays. Frequencies higher than 16000 are required for software speech output, but otherwise a frequency limit of 8000 Hz is enough for all other sound effects. The default is 44.1kHz, the CD replay frequency. Classic.
  • -fragsize 2..16 โ€” a technical little setting ๐Ÿ› ๏ธ: it specifies the size of an audio buffer fragment. These fragments get filled sample by sample and shipped off to the replay hardware as soon as they're full and the hardware can play another sample. Too small โ†’ the buffer gets refilled way too often and you might hear drop-outs because the computation can't keep up with the audio replay. Too long โ†’ the audio latency gets too high and the sound is no longer synchronized with the video out. Important: this option does not give the fragment size itself, it gives the exponent to the base of two โ€” so the true fragment size is two to the power of this exponent. The default is 8, i.e. a fragment size of 256 bytes. You'd rarely need to play with this setting, fr fr.
  • -numfrags 6..256 โ€” the number of buffers, each one the size given by the argument above, used for audio sample generation. More buffers reduce the likelyhood of drop-outs but increase the latency. The default is 16 buffers, and more is rarely useful.
  • -forcestereo bool โ€” forces generation of stereo samples even though mono output is available for the sound chip. Some broken sound implementations โ€” notably ALSA on the Emu10K1 chipset โ€” require this to work correctly under all configuations. Not us fixing their bugs, but okay ๐Ÿ’…

๐Ÿ“ OSSSOUND Options ๐Ÿ“

The Oss driver is a less complex frontend for the Open Sound System audio interface, though it requires a very precise implementation of it. Some emulations, e.g. ALSA, might not be suitable for this frontend, and it rarely provides better quality than HQOss. Since it offers quite similar options as well, we're only describing most of them roughly and referring you to the HQOss frontend for further details. Low effort, high key.

  • -enablesound bool โ€” enables or disables the generation of audio output.
  • -enableconsolespeaker bool โ€” enables or disables the emulation of the Atari console speaker.
  • -consolespeakervolume 0..64 โ€” sets the output volume of the console speaker.
  • -audiodevice filename โ€” names the audio device to send the samples to; this is typically /dev/dsp.
  • -samplefreq 4000..48000 โ€” the sampling frequency in Hz for the audio output.
  • -refillfreq 20..48000 โ€” the frequency in Hz at which the audio samples get recomputed by the emulator. If this is set to a relatively low value while the sampling frequency is high, then quite a lot of samples are computed in one go, but the updating period by which these samples are matched to the true POKEY output is rather low. Also: this refill frequency must be lower than the sampling frequency above. For software speech generation, a refill frequency of 15700 proved most effective. For regular sound output, this frequency can be much lower. And here's the caveat, bestie: for software speech output, the audio kernel interface must meet the specifications of the Open Sound System architecture precisely โ€” some emulations, e.g. ALSA, fail here. Try the HQOss frontend in this case; in most cases it's capable of providing better quality anyhow ๐ŸŒธ
  • -fragsize 2..16 โ€” this is the exponent for the base of two that gives you the size of an audio buffer fragment, in bytes. It's basically the same idea as the fragment size over in the HQOss frontend, and we already spilled all the tea about it above. โœจ
  • -numfrags 1..256 โ€” how many buffers get used to generate your audio samples. Two buffers means the audio output is double-buffered. Ngl, more than four buffers is rarely useful for this driver, which is why four is the default. ๐Ÿ’…
  • -forcestereo bool โ€” forces it to generate stereo samples even when mono output is actually available for the sound chip. Some sound implementations are just straight-up broken, most famously ALSA on the Emu10K1 chipset, and they need this turned on to work correctly in all configurations. ๐Ÿ˜ญ

๐ŸŽ€ WAV Options ๐ŸŽ€

The WAV frontend is the alternative audio output module that records the generated sound instead of playing it โ€” or at least, that's its main character intention. WAV also offers playback of the recorded sound, but because of timing restrictions the quality of that sound is โ€” sometimes noticeably โ€” worse than what you'd get from the Oss or HQOss module, and worse than the sound that actually got recorded into the final .wav file. But like I said: the quality of the output file itself will be perfect. ๐Ÿ’–

  • -enablerecording bool โ€” turns recording to the wav output file on or off. When it's enabled, the emulator starts recording the moment the emulated machine starts running, though the recorded file gets disposed of and re-written from scratch on a cold-reset, like the one generated by the F7 key. To record game music, bestie, the move is: first enable the recording, then start the game, let the music play, and interrupt the music by entering the configuration menu with the F1 shortcut. Then turn recording off. That leaves the recorded file intact. ๐ŸŽต
  • -enableplayback bool โ€” enables or disables playback of the recorded data. If this option is on, the WAV frontend will also play the music over an OSS compatible sound driver. It's typically a good idea to enable this one too whenever it's available, i.e. whenever an OSS sound driver exists in the system. Note though, that the quality of the sound output might be noticeably worse than that of the recorded sound inside the output file. ๐Ÿ™ˆ
  • -enableconsolespeaker bool โ€” just like the option of the same name for the OSS sound frontend, this enables or disables generating sound through the console speaker. It's typically used for the keyboard-clicks and the buzzer-sound. ๐ŸŽน
  • -consolespeakervolume 0..64 โ€” sets the volume of the console speaker when it's enabled. This one defaults to 32.
  • -outputfile filespec โ€” defines the full path of the .wav output file the sound gets recorded into. If you don't give this option, the file name defaults to โ€œout.wavโ€. ๐Ÿ“
  • -audiodevice device โ€” sets the name of the OSS sound device. This is typically โ€œ/dev/dspโ€, which is also the default setting for this option.
  • -samplefreq 4000..48000 โ€” sets the sampling frequency in Hz for the recorded .wav file, and by extension also the sampling frequency of the played-back audio output. The smaller it is, the less CPU power you need and the shorter the output file gets for recording the same timespan of music โ€” but the worse the quality gets. This option defaults to 15700 Hz, which is the best compromise between quality and data size. Much higher frequencies make little sense and don't improve quality noticeably. ๐Ÿ“‰
  • -fragsize 2..16 โ€” same as the OSS front-end option of the same name, this sets the exponent for the size of the fragment used for audio playback. It has no influence whatsoever on the output file, it only modifies the behaviour of audio playback. โœจ
  • -numfrags 1..256 โ€” sets the number of audio fragments (buffers) for audio playback, just like the option of the same name in the OSS front-end. It has no influence on the recorded samples.

๐Ÿฆ‹ SDLSound Options ๐Ÿฆ‹

The next audio front-end generates sound through the Standard Direct Media Library โ€” SDL for short โ€” all provided you have an SDL library and the required development files installed on your host. The quality of the SDL output is close to that of the HQOss frontend, though because of the different driver architecture, the SDL driver is unfortunately more likely to generate drop-outs. It also requires longer fragments, so it has a higher latency โ€” but it's super portable since SDL exists on a whole variety of platforms. ๐ŸŒˆ

  • -enablesound bool โ€” enables or disables sound generation through SDL, same as the equivalent option for the OSS and WAV audio front-ends.
  • -enableconsolespeaker bool โ€” toggles the console speaker emulation on or off. The emulation is enabled by default.
  • -consolespeakervolume 0..64 โ€” adjusts the volume of the console speaker. This setting defaults to a medium volume of 32.
  • -samplefreq 4000..48000 โ€” adjusts the sampling frequency for audio generation in Hz = samples per second. Higher sampling frequencies give you closer sound output emulation, but they also enlarge the CPU load on the system. The sampling frequency defaults to 44100 Hz, i.e. CD quality. On weaker systems you might have to lower this setting. ๐Ÿ‘‘
  • -fragsize 2..16 โ€” selects the size of an audio output buffer, expressed as the exponent for the base of two. The smaller the fragment size, the more often the audio output gets updated to reflect the audio register setting of the POKEY chip, and the more natural the audio output becomes. But if the fragment size is too small, then the audio output degrades quickly, because the emulation will no longer be able to refill the output buffers in time. The optimal setting for this value is around nine, which is also the default. ๐Ÿ’œ
  • -forcestereo bool โ€” forces it to generate stereo samples even when mono output is available for the sound chip. Some broken sound implementations, notably ALSA on the Emu10K1 chipset, require this to work correctly under all configurations.

๐Ÿ”ฅ DirectX Sound Options ๐Ÿ”ฅ

This audio front-end is only available for win32 compatible platforms and requires at least DirectX 8.0 installed on the host machine. It offers the highest audio quality available under the win32 operating system at minimal latency. It's giving premium. ๐Ÿ’…

The following options are available for DIRECTX sound:

  • -enablesound bool โ€” enables or disables audio output. It's enabled by default.
  • -enableconsolespeaker bool โ€” turns emulation of the console speaker on or off. This speaker generates the keyboard click and buzzer sounds, but otherwise it's not used very frequently; it's enabled by default.
  • -consolespeakervolume 0..64 โ€” controls the volume of the console speaker. The default setting is 32, though higher volumes are not recommended since they'll cause distortion when mixed with the regular POKEY output. ๐Ÿ˜ฌ
  • -samplefreq 4000..48000 โ€” selects the sampling frequency in samples per second. The default is 22050 Hz, i.e. half the frequency of an audio CD. Higher frequencies are not recommended for DirectX, because otherwise the CPU load gets very high.
  • -fragsize 2..12 โ€” sets the size of one audio buffer, also called a โ€œfragmentโ€, by defining its exponent to the base of two. So increasing this setting by one doubles the size of one audio buffer โ€” a setting of eight causes buffers that are 2^8 = 256 samples long. This is also the default buffer setting and a good compromize between latency and quality for fast, up-to-date hardware. Slower systems might need higher values; if you hear audio drop-outs, increase this value. ๐Ÿ”Š
  • -numfrags 6..16 โ€” defines the number of audio buffers of the above size to be allocated. A higher number allocates more buffers, causing higher latency, but also lowering the probability of drop-outs. The default is six buffers, but you should increase this number if the audio output isn't smooth.

๐ŸŒธ ALSASound Options ๐ŸŒธ

The last available audio front-end uses the ALSA sound drivers available on Linux and the asoundlib API. Both of those, plus their development files, must be available at compile time to provide this interface.

If available, ALSA provides high quality sound similar to the HQOSS frontend, though its demands concerning CPU power are very moderate and lower than that of other frontends. Lowkey the most chill one. โœจ

The following options are available for ALSA:

  • -enablesound bool โ€” enables or disables the sound output. This defaults to on.
  • -enableconsolespeaker bool โ€” controls emulation of the console speaker; this option is turned on by default.
  • -consolespeakervolumne 0..64 โ€” selects the volume of the console speaker. It's set to 32 by default; higher volumes might cause distortion in the sound output.
  • -audiocard name โ€” selects the audio hardware ALSA shall send the samples to. This is not a device specification in the sense of a path name. It defaults to โ€œhw:0,0โ€, which addresses the first available audio hardware handled by ALSA. Further audio cards are named โ€œhw:1,0โ€ and so on. Even though Atari++ supports a wide range of sampling formats natively, some exotic cards might require help from ALSA. To enable this additional software support, substitute โ€œhwโ€ with โ€œplughwโ€, e.g. specify โ€œplughw:1,0โ€ as the device name. This enables an additional software conversion inside ALSA. ๐ŸŽง
  • -samplefreq 4000..48000 โ€” selects the sampling frequency in samples per second. The default is 44100 Hz, i.e. CD quality.
  • -fragsize 2..16 โ€” defines the size of an audio buffer fragment as the exponent to the base of two. This works very similarly to all the other audio frontends and I'm not explaining it again, bestie. ALSA allows a relatively small default of 8 here, meaning fragments of 2^8 = 256 bytes.
  • -numfrags 6..256 โ€” defines the size of the audio buffer in fragments. The more fragments, the lower the probability of drop-outs, but the higher the latency. The number of fragments defaults to 12.
  • -forcestereo bool โ€” this one forces stereo samples to be generated even when mono output is available for the sound chip. Why would you do that? Because some sound implementations are lowkey broken, notably ALSA on the Emu10K1 chipset, and they may require this to work correctly under all configurations. So if your audio is giving ๐Ÿ’€, try flipping this.

๐Ÿ–ฅ๏ธ X11 Options ๐Ÿ–ฅ๏ธ

okay so this next lil squad of options controls the X11 graphical frontend of the Atari++ emulator โ€” but only if you actually picked it with the -frontend X11 option. If you didn't, then the control options of whatever frontend you did select are the ones that apply instead. no cap ๐Ÿซถ

  • -privatecmap bool โ€” set this to on and Atari++ will emulate its own color map for the emulation window output. You only need this if you're running on an 8 bit display and the emulator further complains that it couldn't allocate enough free pens. The downside? ๐Ÿ’€ the colors will get wrong as soon as the mouse pointer leaves the emulator window on an 8 bpp display โ€” but at least you get a display with proper colors otherwise, so tradeoffs bestie.

This option is not at all useful for 16 bpp or any other true-color displays, because the color mapping will be correct all the time otherwise. Therefore, the default for this option is off.

  • -syncx bool โ€” a boolean flag describing whether the X11 frontend shall try to keep the display output in sync with the emulator. If set to off, all rendering operations will be asynchronous, possibly causing some lag between the gameplay and the display ๐Ÿ˜ญ. The downside of enforcing synchronous graphic rendering by setting this to on is that the display refresh must wait for the X server to perform the refresh and to notify the client about it, adding the turn-around times and the net transfer overhead to the display refresh time. So yeah โ€” it is therefore rarely a good idea to enable this option. leave it alone fr.
  • -disableDPMS โ€” disables the display management power signal extension and thus prevents the monitor blanker or screen saver of the operating system from jumping in while you're playing with the emulator. It is usually a good idea to enable this option โœจ (yes pls, no one wants their screen going dark mid-boss-fight).
  • -xvideorendering bool โ€” will use the โ€œXVideoโ€ extension of the X11 system to render graphics on the screen. Unlike the default rendering mode, which builds the image from many colored rectangles, this render mode writes the raw display data into a shared memory region which is then scaled and pushed to the screen directly by the video overlay mechanism of the graphics card when available. Depending on the graphics hardware, this option may provide better performance on lower end hardware ๐Ÿ”ฅ.
  • -renderindirect bool โ€” if set to on, then all rendering happens indirectly to an off-screen pixmap in a first step, then blitting the pixmap in a second step back to the screen. Downside: it's slower, because it requires an additional transfer step ๐ŸŒ. Upside: it makes the display refresh smoother, and the rendering operation itself remains invisible (no tearing jumpscare). Since it makes emulation slower, this option remains off by default.
  • -screenbase filename โ€” selects a filename base for the screen dumps. If a screendump is requested, a counter and a file type extender is appended to this name, and the screen contents are saved to this file. Currently, screen dumps are saved in the Portable Pixmap (ppm) format that is readable by most Linux/Unix tools, e.g. by xv and gimp. The default filename is โ€œScreenDumpโ€.
  • -dumpformat PNM|BMP|PNG โ€” specifies the file format to be used for screen dumps.
    • PNM is the simplistic *nix specific PNM/PPM true color dump file format that is understood by most *nix programs.
    • BMP is the Windows Bitmap format, a very popular but rather aged image file format of the Win world ๐Ÿ’€.
    • PNG is the โ€œPortable Network Graphicsโ€ file format, an image format driven forward by the Open Source community. This file format requires the availibility of the LibPNG.
  • -pixelwidth 1..8 โ€” this option spezifies the magnification degree in horizontal direction by which the pixels of the emulated scren are rendered to the X11 display. The default of the pixelsize option is 2, i.e. a single pixel of the Atari display is rendered twice as large on the X window showing the emulation ๐Ÿ‘‘. Depending on the hardware driver of your graphics board, enlarging the pixelsize might be almost for free with the X11 frontend โ€” free glow-up, we love that.
  • -pixelheight 1..8 โ€” this option controls the magnification of the pixel size in vertical direction, similar to the above option. The default value is 2 as well ๐Ÿ’….
  • -leftedge 0..64 โ€” sets the horizontal position of the first Atari pixel that gets displayed within the X11 window. The pixels left to this pixel are not made visible. This option is useful either to align the size of the X window to the natural size of the screen the window is contained in, to hide the leftmost pixel junk caused by the horizontal ANTIC scrolling, or to remove the hardware border of the window, similar to the operation performed by some TVs ๐Ÿ“บ. This option defaults to 16, just enough to make the HSCROLL artefacts invisible.
  • -topedge 0..64 โ€” sets the first row of the ANTIC display to render to the X11 window. This is otherwise identical to the -leftedge option except that it works in vertical direction. The default of this option is zero.
  • -width 320..480 โ€” sets the total amount of pixels to render into the screen and hence the inner dimension of the X window. Reducing this width can be either useful to fit this window into the screen, or to avoid some pixel junk at the right edge of the ANTIC display. The default width is 352 pixels.
  • -height 192..248 โ€” sets the height of the window in emulated pixels. Since the lowest lines are always left blank anyhow, they need not to be rendered. Therefore, this option defaults to 240.

๐ŸŽฎ SDL Options ๐ŸŽฎ

The next option set controls the layout of the alternate emulator frontend driven by the Simple Direct Media Library, or short, SDL. This library allows fullscreen output, though its overall performance is lower as soon as it requires to upscale the pixels ๐Ÿ˜ฌ. The SDL frontend is activated by the -frontend SDL switch, and only then do the following options apply:

  • -leftedge 0..64 โ€” similar to the X11 Option of the same name, this selects the first visible emulator pixel on the SDL screen. This option defaults to 16.
  • -topedge 0..64 โ€” specifies the first visible row on the screen. The default is to start the display at row 0.
  • -width 320..480 โ€” the width in emulator pixels of the screen to render. The default is 352.
  • -height 192..248 โ€” the height of the emulated display. The default is to drop some lines at the bottom end since they are always blank anyhow: 240 lines are rendered by default.
  • -pixelwidth 1..8 โ€” set the width of one emulator pixel in SDL pixels. The default is that one emulator pixel is represented by one pixel on the SDL screen. Setting this to values larger than two easely degrades the emulator performance ๐Ÿซ .
  • -pixelheight 1..8 โ€” set the height of one emulator pixel in SDL pixels. As already said above, the default is one. Pixel heights larger than two typically slow down the emulator too much to be useful ๐Ÿ˜ญ.
  • -screenbase filename โ€” defines a base file name similar to the X11 screenbase option for screen dumps. The filename of the screen dump is, as above, formed by a counting number and the extender of the file format. Currently, screen snapshots are saved as PPM images.
  • -doublebuffer bool โ€” enables double buffering, provided the implementation of SDL on the host system implements it. Double buffering allows smoother scrolling at the price of a slightly higher CPU load โœจ. At the time of writing, only the win32 version of SDL provides double buffering, the Linux version does not. Thus, enabling this option under Linux does nothing ๐Ÿ’€. However, the renderindirect option of the X11 front-end does something very similar.
  • -fullscreen bool โ€” enables or disables full screen display. The default is to use the full screen display, and it is recommended to use the X11 frontend otherwise as it provides higher performance in this case.
  • -dumpformat PNM|BMP|PNG โ€” specifies the file format to be used for screen dumps.
    • PNM is the simplistic *nix specific PNM/PPM true color dump file format that is understood by most *nix programs.
    • BMP is the Windows Bitmap format, a very popular but rather aged image file format of the Win32 world.
    • PNG is the โ€œPortable Network Graphicsโ€ file format, an image format driven forward by the Open Source community. This file format requires the availibility of the LibPNG.
  • -shieldcursor bool โ€” enables a workaround against an SDL bug that allows a program to overdraw the active mouse pointer, trashing its backing store and leaving invalid graphics behind the pointer if it is moved away ๐Ÿ’€. This workaround will remove the cursor prior the drawing operation to avoid the problem, at the cost of a possibly flickering pointer ๐Ÿ™ˆ.
  • -deblocker bool โ€” enables a deblocking filter that creates rounder and smoother graphics for pixel sizes between two and three. This avoids to some degree the blocky-ness of the emulated display that is caused by the higher and finer resolution of the PC monitor compared to the TV output the Atari hardware was designed for ๐Ÿ“บโœจ.

๐Ÿ”Œ 850INTERFACE Options ๐Ÿ”Œ

The Atari++ contains a complete emulation of the 850 serial interface box, including a boot-able R: handler that would be usually included in the ROM of the interface box ๐Ÿ‘‘. The emulation allows you to use the serial port of the host system as a serial output port of the 850 interface, allowing you to connect a modem to the emulated Atari. The emulation has only two limitations:

  1. It cannot provide some of the exotic baud rates the 850 box is able to generate.
  2. It provides only a single serial port, not four of them.

On the other hand, it offers a true hardware handshake, unlike the Atari 850 ๐Ÿ’…. For more information about the emulator provided R: handler, see below.

okay bestie these next two are all about the 850 interface ๐Ÿ’– tiny section, big vibes:

  • -enable850 bool โ€” turns the 850 interface on or off. If you disable it, the interface box will not react on any SIO commands at all, so it basically pretends to be switched off. iconic behavior honestly ๐Ÿซถ
  • -serialname path โ€” tells the emulator which device name to use for the serial port that the emulated 850 interface uses as its output port. The default is "/dev/ttyS0", aka the first serial output port of the system. no cap โœจ

๐ŸŽ€ CONFIGURATION FILES ๐ŸŽ€

bestie, Atari++ is not just controlled by its absolutely huge amount of command line parameters โ€” it's also adjustable by configuration files ๐ŸŒธ

These configuration files contain the very same options as the command line parameters, with just a few little rules:

  • there is only one option per line
  • an equals = sign separates the option from its value
  • the minus-sign in front of the option is missing

Also, empty lines are allowed, and so are comments starting with the hash-mark # ๐Ÿ’œ

Here's what a typical configuration file looks like:

#
# This is the config file for the atari++ emulator
#
HoldOption      = true
Artefacts       = off
Enable.1        = on
Protect.1       = on
SIOPatch        = on
InstallPDevice  = on
SampleFreq      = 44100
RefillFreq      = 15700
NumFrags        = 4
Joystick.0.Port = DigitalJoystick.0

The Atari++ emulator knows three configuration files:

  1. The system specific configuration file, living at /etc/atari++/atari++.conf
  2. The per-user specific configuration file at ~/.atari++.conf
  3. The per-directory configuration file at ./.atari++.conf

Each later configuration file overloads the defaults of the former one, and then the command line arguments finally overload all of them ๐Ÿ”ฅ

So the strategy is: the least frequently adjusted options should go into the configuration file in the home directory, and the system specific settings go into /etc. chef's kiss ๐ŸŽ€


๐Ÿ—๏ธ KEYMAP ๐Ÿ—๏ธ

The Atari++ emulator uses the following keymap, bestie, listen up ๐Ÿ’…

  • F1 โ€” this key enters the graphical configuration menu. Using this menu should be pretty obvious, since all the options are named exactly like they are in this manual and sorted under the same topics ๐ŸŒˆ The menu is left by the topmost Prefs topic, which also lets you load and save the settings and enter the monitor. For the CURSES front-end the F1 key changes its meaning, because no full menu is available there. In that case, it replaces the Atari resp. inverse-video key ๐Ÿ‘‘
  • F2 โ€” is mapped to the Option console key.
  • F3 โ€” is mapped to the Select console key.
  • F4 โ€” is mapped to the Start console key.
  • F5 โ€” is the Help key, which is otherwise only available on the XL and XE hardware โœจ
  • F6 โ€” is the Reset console key. Its function differs a bit amongst the various models. For the Atari 800 and 400, this key just signals a special NMI interrupt at ANTIC, and the Os resets the system manually. For the XL and XE, this signal is really connected to the CPU reset line. Atari++ emulates this behaivour ๐Ÿ’–
  • F7 โ€” coldstarts the system as if it had been turned off and on again. So unlike F6, this is a true coldstart and not a warmstart ๐ŸŒธ
  • F8 โ€” emulates the Break key, used to stop listings and BASIC programs.
  • F9 โ€” requests a screen dump. Where this screendump goes is a matter of the -screenbase command line option ๐Ÿ“ธ
  • F10 โ€” aborts the emulator immediately, similar to closing the window. bye bestie ๐Ÿ˜ญ
  • F11 and Pause โ€” pauses the emulator. Pressing F11 again continues the emulation โธ๏ธ
  • F12 โ€” enters the on-line monitor that is described below.
  • Home/Clear โ€” emulate the Shift+< sequence, enforcing a clear screen ๐Ÿงผ
  • Insert โ€” inserts a blank character under the cursor by emulating Ctrl+>. If pressed together with shift, a blank line is inserted at the current line position.
  • Del โ€” removes a single character under the cursor by emulating a Ctrl+BS keyboard sequence ๐Ÿ’…
  • Cursor Keys โ€” move the cursor in the indicating direction by holding either +,*,-,= and the Ctrl key down. This works fine most of the time, except for the DDT debugger, which requires these keys pressed without Ctrl for window movement. Do not use the separate cursor keys but the above keys directly for DDT ๐Ÿซถ
  • Esc โ€” emulates, as expected, the ESC key on the Atari keypad.
  • Keypad keys 7,8,9,4,5,6,1,2,3 โ€” are part of the "keypadstick.0" device and a possible emulation source for joystick input; they are also configurable, see the KeypadStick section ๐Ÿ•น๏ธ
  • Keypad keys 0 and Enter โ€” emulate the joystick button of the device as well.
  • ALT โ€” emulates the Atari or InverseVideo key. For some implementations, this key is also emulated by the Windows key ๐ŸชŸ

All other keys have their natural key binding, except for the 5200 game console, which is explained below. This binding is given by the current keyboard layout; this means especially that the keyboard layout is language specific and does not necessarely match the layout of the Atari keyboard. E.g. for a german keyboard, the keys for "y" and "z" work as printed on the PC keyboard, and not as for the (american) Atari keyboard layout. I currently consider this as an advantage ๐Ÿ’œ

๐Ÿ•น๏ธ KEYBOARD INPUT FOR THE 5200 ๐Ÿ•น๏ธ

Keyboard input on the 5200 game system is considerably different, because this console does not have a keyboard โ€” it has a small numeric pad on each of its controllers ๐ŸŽฎ

That pad consists of:

  • the numbers zero to nine
  • the asterisk "*"
  • the hash-mark "#"
  • the buttons labelled "Start", "Pause" and "Reset"

Furthermore, the joysticks have two buttons instead of one, and are actually analog joysticks using the paddle input lines, see above.

The current emulator uses the PC keyboard for all additional keys and does currently not distinguish between the various keypads. A button pressed on the PC keyboard will be read as coming from all game controllers at once. A future version of atari++ may possibly use a different scheme ๐Ÿคทโ€โ™€๏ธ

The following keyboard keys act differently on the 5200 system:

  • F2 โ€” is the "Reset" key on the keypad of the controller. This key is in no way any kind of hardware reset and is dissimilar to the "real" hardware reset which is still triggered by F6. Instead, this key is just an ordinary key that must be read by the loaded game, typically bringing you back to the setup screen.
  • F3 โ€” is the "Pause" key on the keypad. This is also a purely software driven feature the game may or may not support.
  • F4 โ€” is the "Start" key; it typically launches the game ๐Ÿš€
  • keys 0..9 โ€” activate the corresponding keypad keys.
  • H or # โ€” emulates the hash-mark on the keypad controller key. Since the hashmark is not available on all native PC keyboards, the H is available as a replacement ๐Ÿ™ˆ
  • S or * โ€” emulates the asterisk on the controller keypad. Similarly, the S is a suitable emulation for native keyboards with a hard-to-reach asterisk key.
  • Shift โ€” acts as the second trigger button on all external controller keypads.
  • F2 thru F12 โ€” act as usual, see the list above โœจ
  • all other keys โ€” are blind and perform no operation in the 5200 emulation mode ๐Ÿ’€

๐Ÿ–ฅ๏ธ THE CURSES EMULATION ๐Ÿ–ฅ๏ธ

The keyboard input of the CURSES (terminal) front-end is rather limited, because the emulator has considerably less control over the keyboard than under the graphical front-ends ๐Ÿ˜ญ

Note that this emulation replaces the complete front-end of the emulator, it is not fit to script it, e.g. feed input to it from a file. For that, better replace operating system editor functions and use the InstallEDevice function.

In the curses front-end, most keys work as expected, with some limitations:

  • F1 โ€” does not provide a full menu, which is not available due to lack of graphics output. Instead, the machine must be configured manually from the command line or the configuration files. The F1 key rather maps to the Atari or InverseVideo key, as the state of the ALT key is not directly accessible from the CURSES interface ๐Ÿ’…
  • CAPS โ€” is not directly available because the CapsLock key is read by the host operating system and is not forwarded to the emulation. Instead, the emulator sends a CAPS key event after each reset, triggering the system to low-caps, which is the default under most host operating systems, and then setting the Shift key of the emulated machine according to the case of the inserted character. This makes CAPS "appear" to work right for most situations โ€” unless a program fiddles with the operating system and alters the CAPS state manually, or performs a software-driven reset. In that case, the ASCII TILDE that is " ~ " will emulate a press on the CAPS key of the host ๐ŸŒ€
  • Requesters and Menus โ€” requesters and error messages will be emulated on the console by text-driven menus, allowing you to select a choice by typing the indicated character ๐Ÿ‘‘
  • Graphics Output โ€” the graphics emulation is limited to text based ANTIC modes, limited to the standard character set. Some of the text graphics can be emulated, ASCII-Art might work to a limited degree, but bitmap graphics output will not appear on the console. Some limited support for horizontal scrolling is available, though ๐ŸŒˆ

๐Ÿ’พ SNAPSHOT FILES ๐Ÿ’พ

okay bestie, this is genuinely one of the slayest features and you're gonna be obsessed. atari++ lets you take a snapshot of the complete machine state at literally any moment mid-game, save that state to a file, and then restart the game later from exactly that position. not just useful โ€” it's iconic. want to interrupt a game temporarily because you've got better things to do in the meantime? covered. want to grind through a hard game puzzle several times without crying? also covered. ๐Ÿซถ

So to create a snapshot file, you press F1 on your keyboard to pop the menu, pick the Prefs item on the left hand side list, and drop the name of the state file into the bottommost gadget labelled โ€œSave State Toโ€. that's it, that's the whole ritual โœจ

To restore a machine state โ€” i.e. to load the snapshot file โ€” use the gadget โ€œLoad State Fromโ€ right on top of it, or use the command line option -state filename, which expects the name of your snapshot file.

now here's the part where you gotta pay attention, because it's giving โœจimportantโœจ: the snapshot file contains only the part of the inner machine state that is not covered by the configuration file. for example, the snapshot file will NOT contain the currently active ROM image, because that image is already sufficiently specified by the configuration. so if your configuration at the time you made the snapshot differs from your default configuration, you should also save that configuration, and load it along with the snapshot. snapshot files extend configuration files โ€” they are not independent from the emulator configuration. periodt.

๐ŸŒˆ THE H: HANDLER ๐ŸŒˆ

so the emulator ships an optional interface from the emulated Atari to the host environment, and it's called the H: handler โ€” it makes parts of the host's filing system visible inside the emulation. main character energy fr fr. ๐Ÿ’…

To actually use this handler, it has to be enabled by the -InstallHDevice on command line option, or a similar option within the configuration files. what this does is replace the C: cassette interface โ€” which is rarely, if ever, useful โ€” with the host interface filehandler. and this handler provides four units, named H1: to H4:, opening four directories of the host system within the emulator. those directories get configured by the -H1Dir to -H4Dir command line options, which expect path name(s) to host system directories.

๐ŸŒธ FILE NAMES AND PATTERN MATCHING ๐ŸŒธ

Similar to the standard file management systems DOS 2.0S and upper, the H: handler automatically resolves patterns within filenames. The following wildcards are supported:

  • * โ€” matches a sequence of any, possibly zero, length of any characters, quite similar to the bash or the csh.
  • ? โ€” matches one single character.
  • - โ€” matches any character and ignores the rest of the pattern.

Unlike the standard file management systems, the dot . has no special meaning for the H: device โ€” except that file names are truncated to eight characters in front and three characters beyond it. this is a backwards compatibility feature, so you can run most Atari Os compliant programs on the H: device without additions. iykyk.

The handler will furthermore ignore cases when comparing the requested file name with a file name on the host system. Files generated by the emulator will use lower case for convenience. cute, right? ๐ŸŽ€

๐Ÿงš COMMAND SET ๐Ÿงš

The H: handler supports the following IO commands:

  • CMD 3: OPEN โ€” used by the BASIC OPEN #channel,aux1,aux2,"H:filespec" command. The aux2 specifier will be ignored. valid aux1 values are:
    • 4 โ€” open for read-only
    • 6 โ€” open the directory
    • 7 โ€” open the directory
    • 8 โ€” create for write-only
    • 9 โ€” open for append write-only
    • 12 โ€” open for read, write and append
    • 13 โ€” create for read, write and append

This follows closely the DOS 2.0S conventions, with the addition that mode 12 is able to write past EOF and mode 13 also creates files. Mode 7 is an addition that was made for compatibility of DOS 2.XL by the author.

The filespec follows the file name convention explained in the previous subsection. The directory listing generated by codes 6 and 7 will be formatted similar to the DOS 2.0S output for the same request, but the amount of free sectors will always show up as "999". why? because there is basically no visual storage limit for a tiny Atari file system inside a Unix/Linux workstation, bestie. Files that are not user-writeable appear as "locked" and are marked with an asterisk in the first column. Similarly, file locking and unlocking changes the user-writeable protection bit of the host system. ๐Ÿ’€

  • CMD 5: GET RECORD โ€” reads characters up to an EOL character, or up to the buffer end, into a buffer. This is a standard command supplied by all handlers. It implements the BASIC INPUT #channel,var and related commands.
  • CMD 7: GET CHARACTERS โ€” reads a block of characters into a buffer. This is a standard command, consult the Atari technical manual for details. Not reachable from BASIC.
  • CMD 9: PUT RECORD โ€” writes characters up to an EOL or up to the end of the buffer into the opened stream. Also part of the standard command set. Not reachable from BASIC, but related to the BASIC command PRINT #channel,data.
  • CMD 11: PUT CHARACTERS โ€” writes a block of characters into a stream. A standard command. Not reachable within BASIC, but related to the BASIC commands PUT #channel,value and PRINT #channel,data.
  • CMD 12: CLOSE โ€” releases the given stream, closes the file on the host system and frees all buffers. This command is considered harmless on streams already closed. This implements the BASIC CLOSE #channel command.
  • CMD 13: STATUS โ€” requests the status of the given stream. It returns status code 133 if the channel is not open, status code 1 if the channel generated no error, status code 3 if you are about to read from the EOF on the next go, or the last error should the stream be in an error condition otherwise. This follows standard conventions.
  • CMD 32: RENAME โ€” implements the BASIC XIO 32,#channel,aux1,aux2,"H:oldname,newname" command. Note that the file specification of this command consists of an existing filename, a comma ,, and a new file name. This command attempts to rename the existing file to a new name.
  • CMD 33: DELETE โ€” implements the BASIC XIO 33,#channel,aux1,aux2,"H:filespec" command and attempts to remove (delete) the given files or patterns. It will fail if the files are not user-readable, i.e. appear "locked" in the emulator.
  • CMD 34: VALIDATE โ€” an extension following DOS 3 conventions, also reachable within BASIC with XIO 34. This command will check whether the given filespec is well-formed and will return an error code if not. It does not attempt to open any file.
  • CMD 35: UNPROTECT โ€” implements the XIO 35 command which "unlocks" the given file(s) and allows write-access into it. The host system reflects this operation by enabling the user-writeable permission bit.
  • CMD 36: PROTECT โ€” implements the BASIC XIO 36 command and "locks" the filespec by removing the user write-permission bit.
  • CMD 37: POINT โ€” unlike command 32 to 36 above, this expects that the given channel is already linked to an open stream. It implements the basic POINT #ch,sector,byte command for placing the file pointer within the file. The Os. CIO places the sector offset in AUX4 and AUX5 and the byte offset into AUX3. However, conventions for file addressing are different from DOS 2.0S and are more orthogonal. The H: handler appears to have sectors of 256 bytes each, numbered linearly from 0 up within each file. Sectors are not global within the filing sytem but local to the file linked to the channel. This is somewhat similar to the DOS 3 implementation of POINT. ๐Ÿฆ‹
  • CMD 38: NOTE โ€” similar to command 37, this command expects an open stream on the same channel, implementing the BASIC NOTE #ch,sector,byte command. It reads the file pointer within the opened file and returns byte and sector offsets using the same conventions as POINT. Bytes are numbered consequently from 0 to 255, and sectors are numbered from the start of the file from zero up, each of them but possibly the last carrying 256 bytes of data. As long as programs use the values returned by NOTE as opaque values and avoid to perform algebra on them, this remains compatible to the DOS 2.0S. However, programs expecting 125 byte sectors and absolute sectoring are likely to fail. ๐Ÿ˜ญ
  • CMD 40: RESOLVE โ€” this command resolves a wild card sequence by a real filename. It reads the wildcard from IOCBAdr, and places the resolved filename back into the buffer pointed to by IOCBAdr as well. To be able to resolve non-unique wildcards, IOCBAux2 defines which of the non-unqiue matches shall be returned. It counts from one up, and returns the n-th found match to the specified wildcard.
  • CMD 41: BINARY LOAD โ€” load an executable file, and possibly initialize and run it if the file AUX2 specifies whether the loaded file shall be initialized or run. If set to 192, the file is initialized and run, 128 means "init only", 64 just runs, but does not initialize the file, and 0 neither runs nor initializes the file.
  • Unimplemented commands โ€” The H: device does not implement the various format commands, for obvious reason. It also doesn't implement some DOS 2.XL resp. DOS 3 extensions to initialize a DOS. Especially, opening the DOS.SYS file for writing will not perform anything special. ๐Ÿ™ˆ

๐ŸŽ€ THE E: HANDLER ๐ŸŽ€

okay so this one is the operating system editor handler โ€” it's the lil guy whose whole job is grabbing user input off the screen and then yeeting data right back onto it. โœจ and normally? bestie, you leave it ALONE. every component it needs is already emulated so it just... does its thing, no notes, no meddling. ๐Ÿ’…

but if you're tryna script the editor, sometimes it's genuinely useful to redirect the output that would normally go to the machine's editor into a Unix or Windows file, and also pull the input that would normally come from the keyboard out of a file too. ๐Ÿซถ

for that, you use the operating system patch -installedevice, which swaps the Atari handler out for a patch that runs on the host system. input data gets read from the standard input of the emulator command, and output goes both to the emulator front-end and the standard-output of the emulator command. slay. ๐Ÿ‘‘

but ngl, only a limited number of control character transpositions are available. ๐Ÿ˜ญ specifically, these standard ANSI control characters get recognized and translated:
  • \t โ€” Horizontal TAB
  • \n โ€” New Line, transposed to EOL
  • \b โ€” Backspace
  • \a โ€” Bell
  • \f โ€” Form Feed, transposed to Clear Screen

Cursor movement and other advanced sequences? yeah those are left alone, fr fr. they're output device dependent and need a way more careful analysis that depends on which console type you're using. ๐Ÿง so if you need to run the emulator in a console, consider the curses front-end instead โ€” that's the move.

Another limitation of the E: device patch: it obviously can't emulate the full-screen editor buffer of the Atari ROM, because it has no access to the screen of the emulator. ๐Ÿ’€ instead, only the line-buffering of the console is available, meaning the emulator will NOT be able to see your input unless you press RETURN. periodt.

and this also holds for the keyboard device, for which a patch is provided along with this option. so specifically: if software running in the emulator requires you to press a key, you need to terminate that input by RETURN to make it accessible to the emulator. ๐ŸŒธ

๐Ÿ’– THE R: HANDLER ๐Ÿ’–

okay so bestie, the R: handler is literally part of the emulated 850 interface box โ€” it is not specific to the emulator, a real 850 would also provide this handler. ๐Ÿ’…

but here's the tea ๐Ÿต โ€” unlike the H: handler, the R: handler is not installed by the emulator directly, and it is not available unless it is booted by a dedicated file. An Atari DOS distribution should either contain a file named HANDLERS.SYS or an appropriate AUTORUN.SYS file to bootstrap this handler. Dos 2.5, for example, provides a setup program to generate the appropriate file. This bootstrap code is not specific to the emulator and works generically for the real, as for the emulated 850 interface box. For the real 850, the bootstrap code loads code from the interface into the Atari; for Atari++, this code is part of the 850 emulation, but uses otherwise the same command set as the real 850, providing maximal compatibility. ๐Ÿซถ

The emulator even emulates some of the limitations of the 850 system, because accuracy is the vibe: once opened, the R: handler is in block mode, only allowing you to write blocks of data asynchroniously, but not allowing you to receive data. In block mode, 850 I/O can be mixed freely with any other disk I/O. โœจ

With a special XIO command, the handler must be put into concurrent mode to be able to read and write data synchroniously. In this mode, data gets sent out immediately as it is written, and input data can be received back as soon as it arrives, but any other device on the serial chain is unreachable and cannot be used savely. Thus, the disk is unavailable in concurrent mode. ๐Ÿ˜ญ


๐ŸŽ€ COMMAND SET ๐ŸŽ€

The following set of CIO commands are made available by the R: handler:

๐Ÿ”“ CMD 3: OPEN

Open a channel to the R: handler. Aux1 is either 8 for output only in block mode, 5 for input with concurrent mode support, 9 for output in block and concurrent mode, and 13 for input/output, including concurrent mode support. Aux2 is ignored. ๐Ÿšช

๐Ÿ“– CMD 5: GET RECORD

Reads characters up to an EOL character, or up to the buffer end, into a buffer. Reading is only available in concurrent mode. Read characters can be optionally translated from ASCII into ATASCII, see CMD 38 below. ๐Ÿ‘‘

๐Ÿ“š CMD 7: GET CHARACTERS

Reads a block of characters into a buffer. Again, only available in concurrent mode. ๐Ÿงš

โœ๏ธ CMD 9: PUT RECORD

Writes characters up to an EOL or up to the end of the buffer into the opened stream. Available in block mode or in concurrent mode. In block mode, data is buffered and transmitted as soon as either the buffer becomes full, or an EOL is sent. In concurrent mode, data is sent out immediately. In both modes, characters can be optionally translated from ATASCII into ASCII. ๐Ÿ’Œ

๐Ÿ“ CMD 11: PUT CHARACTERS

Writes a block of characters into a stream, not necessarely terminated by an EOL. Otherwise identically to the above. ๐Ÿ”ฅ

๐Ÿšช CMD 12: CLOSE

Releases the given stream, possibly empties the buffer in block mode, or waits until the write buffer is empty in concurrent mode. โœจ

๐Ÿ” CMD 13: STATUS

Requests the status of the given stream. Additionally, memory locations $2ea to $2ed are filled with useful information. Location $2ea contains the error flags of the serial transfer as follows:

  • Bit 7 โ€” received a framing error
  • Bit 6 โ€” input register overrun error
  • Bit 5 โ€” parity error detected
  • Bit 4 โ€” input buffer overrun error

The difference between bit 6 and bit 4 is that bit 6 gets set if the emulated Atari could not react fast enough on interrupts, and bit 4 gets set if the user-provided input buffer overruns in receive mode, though the data could have been catched successfully. ๐Ÿ˜ค

Location $2eb contains the state of the handshake lines in block mode:

  • Bit 7 โ€” current status of the DSR line
  • Bit 6 โ€” previous status of the DSR
  • Bit 5 โ€” current status of the CTS line
  • Bit 4 โ€” previous status of the CTS line
  • Bit 3 โ€” current status of the CD line
  • Bit 2 โ€” previous status of the CD line
  • Bits 1,0 โ€” unused, reserved

The history bits mirror the state of the lines that has been returned by the previous โ€œSTATUSโ€ command. ๐Ÿ‘€

Locations $2ec to $2ed are unassigned in block mode.

In concurrent mode, $2eb and $2ec contain the low- and high-byte representing the number of characters in the input buffers, respectively. Location $2ed contains the number of characters in the output buffer. ๐ŸŒˆ

๐Ÿ’ฅ CMD 32: FORCE

Flushes the output buffer in block mode, or waits until the output buffer has been transmitted in concurrent mode. ๐Ÿ’…

๐ŸŽ›๏ธ CMD 34: SETLINES

Only available in block mode, not in concurrent mode. This command selects the states of the output lines RTS and DTR. On the real 850, the state of the data line TxD can be selected, too. The bits in Aux1 are interpreted as follows:

  • Bit 7 โ€” change the state of the DTR line
  • Bit 6 โ€” new state of DTR if bit 7 is on
  • Bit 5 โ€” change the state of the RTS line
  • Bit 4 โ€” new state of RTS if bit 5 is on
  • Bit 3 โ€” ignored, reserved
  • Bit 2 โ€” ignored, reserved
  • Bit 1 โ€” change the state of the TxD line
  • Bit 0 โ€” new state of TxD if bit 1 is on (unsupported)

Currently, the emulator does not support direct state changes on TxD, though. The value of Aux2 is ignored. ๐Ÿ™ˆ

โฑ๏ธ CMD 36: SETBAUD

Specifies the baud rate and other serial transfer parameters, and handshaking. Only available in block mode, not available in concurrent mode. The bits in Aux1 are interpreted as follows:

If bit 7 is set, at least two, maybe more stop bits are generated. If the bit is clear, one stop bit, maybe more can be generated. Bit 6 is unsed, Bits 5 and 4 specify the number of data bits: If set to zero, eight data bits are transmitted, for 16 (bits = 0,1 resp.) seven bits are used, for 32 (bits = 1,0) six data bits are generated, and for 48 (bits = 1,1) five data bits are sent. Bits 3 to 0 define the baud rate according to this table:

  • Value 0 โ€” remain unchanged
  • Value 1 โ€” 45.5 (not emulated)
  • Value 2 โ€” 50
  • Value 3 โ€” 56.875 (not emulated)
  • Value 4 โ€” 75
  • Value 5 โ€” 110
  • Value 6 โ€” 134.5 (emulated as 134 baud)
  • Value 7 โ€” 150
  • Value 8 โ€” 300
  • Value 9 โ€” 600
  • Value 10 โ€” 1200
  • Value 11 โ€” 1800
  • Value 12 โ€” 2400
  • Value 13 โ€” 4800
  • Value 14 โ€” 9600
  • Value 15 โ€” 9600

Note that values 14 and 15 generate the same rate. ๐Ÿซ 

The bits of Aux2 indicate which serial lines have to be monitored if concurrent mode is entered. If the selected serial lines are not set, an error is generated. For the emulator, monitoring of CTS also enables hardware handshake.

  • Bits 7..3 โ€” reserved, unused
  • Bit 2 โ€” monitor DSR
  • Bit 1 โ€” monitor CTS, enable hardware handshake
  • Bit 0 โ€” monitor CD

๐Ÿ”ค CMD 38: SETPARITY

This command is available in block as well as in concurrent mode. It selects character translations from ASCII into ATASCII and vice versa, and selects input and output parity. The bits in Aux1 have the following meaning:

  • Bit 7 โ€” reserved, unused
  • Bit 6 โ€” if enabled, a LineFeed is inserted after each generated CR
  • Bits 5,4 โ€” ASCII<->ATASCII translation, see below.
  • Bits 3,2 โ€” input parity
  • Bits 1,0 โ€” output parity

If the character translation is set to 0, EOL is translated to CR (not LF!) and vice versa, and bit 7 is stripped off. If set to 16 (bits = 0,1), additionally non-ASCII characters are not written, resp. replaced by Aux2 on input. ๐Ÿ‘‘

If the parity bits are set to zero, data is read or written โ€œas isโ€. This especially implies that parity bits and stop bits of the input data are not stripped off. Furthermore, on output only eight data bits can be generated, unless the upper bits are set to one manually to emulate stop bits. ๐Ÿ’€

If the parity bits are set to one (bits = 0,1), odd parity is generated or checked for. This works only for seven or less data bits.

For the parity bits set to two (bits = 1,0), even parity is generated or checked for seven or less data bits.

For parity bits set to three (both bits set, bits = 1,1), the parity bit is stripped off on input, and always set on output (parity = SPACE). โœจ

Aux2 of this command specifies a โ€œgarbadge characterโ€ that gets inserted for full character translation whenever a non-ATASCII character is received. ๐Ÿ“

๐Ÿš€ CMD 40: STARTCONCURRENT

Enters the concurrent mode from block mode. The only way to leave the concurrent mode again is to close and re-open the channel. Aux1 and Aux2 are irrelevant for this command, but IOCBAdr and IOCBLen might provide the location and size of an optional input buffer where incoming data is kept until it is read off. This buffer should better be large for โ€œhigherโ€ baud rates. If no input buffer is supplied, i.e. IOCBAdr is set to NULL, the handler will provide a short 32 byte input buffer. ๐Ÿซถ

On entering concurrent mode, the input lines specified by the โ€œSETBAUDโ€ command are monitored once. If the selected lines are not set, an error is generated. The real 850 interface does not provide full hardware handshaking, the emulated 850 does by monitoring CTS. ๐Ÿ‘‘


๐ŸŒˆ THE OS ROM EMULATION ๐ŸŒˆ

The Atari++ emulator provides its own operating system in case no Atari ROM image is available. This makes the emulator self-contained as you don't require to hold any usage rights on the original ROMs to run it. The built-in ROM implements a full Atari XL operating system and tries to be compatible to the XL ROM in most aspects; however, since it is a re-implementation, absolute ROM addresses and implementation details may, and will, differ. The paragraphs below give a brief overview on the ROM features, the subsections discuss the features in more detail. ๐Ÿ‘‘โœจ

๐ŸŽ€ Built-in FMS (DOS)

okay so the built-in operating system comes with its own file management system, which is a whole different situation from the original Atari ROMs. everyone classically calls this the DOS (Disk Operating System), which is lowkey imprecise but whatever, we've all been doing it. This FMS steps in whenever there's no bootable disk available on bootstrap. Why do we love her? Because she lets you load and save binary images so easily without needing an Atari copyrighted FMS at all. ๐Ÿ’… For the deets, go look at the FMS subsection below.

๐Ÿฆ‹ Parallel Port Support

has been dropped. Periodt. The reason is that Atari++ doesn't emulate any parallel port devices, and also the author literally has no usable documentation about it. So like... nothing to go on, bestie. ๐Ÿ™ˆ

โœจ The MathPack

is classically not considered part of the operating system, but it's emulated fully here โ€” with all documented entry points and some undocumented ones the author is aware of. The emulation is complete enough to let BASIC and a ton of other programs operate properly, except that the re-implementation is usually a little bit faster and sometimes considerably faster. ๐Ÿ‘‘

You might also wanna consider the MathPack patch option, which evaluates the mathematical operations on the host CPU and improves the speed beyond what's even achievable with the 6502 implementation. iconic behaviour honestly.

๐Ÿ’€ The C: Tape handler

is replaced by a dummy. Not because we're being shady โ€” it's because Atari++ doesn't emulate the tape device, and the ROM space was required. sorry bestie, she had to go. ๐Ÿซถ


๐ŸŒˆ CHARACTER GENERATOR

The international character set at position 0xcc00 and up has been slightly modified:

  • Character position 8 (Ctrl-H) is now the Euro-sign ๐Ÿ’ถ
  • Character position 96 (Ctrl-.) is the german sharp-s
  • The pound sign and the inverted exclamation mark are no longer available

that's the trade, no cap.


โšก INTERRUPT HANDLING

The Os NMI handler also checks the ANTIC Reset NMI signal and, if it's detected, jumps indirectly through the vector in location $24e. That vector points to the warmstart Os vector. Unknown NMI sources are ignored, unlike the original Os which handles them as VBIs. ๐Ÿ™ƒ

๐Ÿ”ฅ VBI Handler

The built-in Os vertical retrace handler (VBI) does not check whether TRIG3 and its shadow-register coincide. This avoids a couple of deadlock situations in various games that overwrite the shadow register โ€” so yeah, it's saving the gamers. ๐ŸŽฎ VBI handling of 1200XL keyboard features is not present, since atari++ doesn't emulate these keys and the author has no precise documentation about them.

๐Ÿ”ฅ IRQ Handler

The IRQ handler is more streamlined than the original IRQ handler. It also no longer handles any parallel port related interrupts, since they are never generated by the emulator. bye bestie ๐Ÿ‘‹


๐Ÿ‘‘ KERNEL

๐Ÿงš Parallel port call-ins

have been replaced by dummies.

๐Ÿงš $e48f: BOOT850

This is a new kernel-call that bootstraps the 850 interface handler thru SIO. It should typically be used by a minimal HANDLERS.SYS file that contains nothing but a RUN-vector to this call-in.

๐Ÿงš $e45c: SETIRQVECTOR

The SetIRQVector call-in can now also savely install IRQs as well, without requiring the caller to set the interrupt bit of the CPU. no extra steps, we love that for her.

๐Ÿงš $e492: RUNDUP

This vector launches the DUP keyboard command processor. The DUP vector at $a,$b points to this address by default. The built-in DUP can be replaced by a custom DUP by changing the reset-resident vector at $3f6. customize away, bestie โœจ

๐Ÿงš $e498: FMSINIT

This vector initializes the built-in FMS. The Os reset initializes the ROM-based FMS thru this vector if no bootable disk is found.


๐ŸŒธ RESET/Bootstrap

๐Ÿ“ Tape bootstrap

Since the built-in Os does not implement a usable tape device, tape bootstrap is no longer supported. The CASINIT vector (0x02/0x03) is, however, emulated properly. so like, the vector is fine, the tape is not ๐Ÿ’€

๐Ÿ“ Disk bootstrap

The built-in Os tries to bootstrap the disk as usual, but does not loop forever in case it detects that no disk is inserted in the drive. If a usable boot block is found, the resident FMS is not installed and a disk-based DOS can replace it, as usual.

The resident FMS is launched if either:

  • no usable boot block is found,
  • no usable disk is found,
  • or the user holds down the START key on bootstrap.

An unusable boot block is indicated by a bootstrap address of zero, thus by a blank boot block. Note that START is no longer an indication for tape bootstrap, since there is no tape support. In case the built-in FMS gains control in the boot process, see below in the FMS subsection for further bootstrap activity. ๐Ÿ‘€

๐Ÿ“ 850 interface bootstrap

In case the disk bootstrap failed because no disk is inserted, the ROM also tries to bootstrap the 850 interface box, since no HANDLERS.SYS file can be loaded then.


๐Ÿ’… SELFTEST

The ROM space occupied by the self-test was required for the DOS command line (the DUP) and is therefore no longer part of the Os. Instead, the following color codes appear on the screen if the power-on tests fail:

Color code RED

The RAM test failed โ€” a faulty RAM chip has been detected. ๐Ÿ˜ญ

Color code PINK

The ROM checksum is faulty. ๐ŸŽ€

Color code BLUE

The bootstrap code could not open the initial editor handler.

so if your screen is looking like a whole mood board, that's your diagnostic. read the color, bestie.

๐ŸŒˆ SERIAL I/O (SIO)

โญ SIO interrupts

The serial communication is initiated thru the Pokey XMTDONE interrupt. This makes it easier for future extensions to relocate disk buffers under the Os ROM. future-proofing, we love to see it.

โญ Parallel port handling

of SIO communications has been dropped due to lack of ROM space and documentation.

โญ Tape device handling

is no longer provided by SIO, since Atari++ doesn't emulate the tape anyhow. Trying to use the tape thru SIO will now initiate a standard serial communication and will no longer use two-tone modulation. Thus, tapes won't work as expected. ๐Ÿซ 


๐Ÿ’œ Resident Disk handler (DISKINTERF)

๐ŸŒธ Format command

The DISKINTERF vector handles now the enhanced density format command of the 1050 floppy drive correctly. Thus, it supports the 1050 command set fully. slay. ๐Ÿ’…

๐ŸŒธ Parallel port I/O

thru DISKINTERF via SIO is no longer possible, since SIO does not try to interact with the parallel port any more.


๐Ÿฆ‹ CENTRAL I/O (CIO)

๐ŸŒŸ CIO CMD_OPEN

The CIO OPEN command installs now the PUT ONE BYTE vector before calling the OPEN vector of the corresponding handler. This allows the handler to overload this vector in order to implement โ€œburstingโ€ more easily. Currently, the FMS makes use of this feature to avoid the check whether it was called from the BASIC ROM that incorrectly uses this vector. โœจ

๐ŸŒŸ CIO HATABS extension

thru the parallel port linked list is not implemented, since the author has no sufficient documentation about its implementation and usage.

๐ŸŒŸ CIO handler bootstrap

is no longer supported due to lack of documentation.


๐Ÿ’€ THE C: TAPE HANDLER

is only a dummy that returns error conditions on all I/O operations. It only remained in the ROM to allow the H: handler to patch it over. so she's not really there, she's just holding the spot, iykyk. ๐Ÿ™ˆ


๐Ÿ‘‘ THE K: KEYBOARD HANDLER

works like its equivalent in the Atari 800XL ROM, except that it does not check for Atari 1200XL function keys. Extended editor keyboard functions are provided to the best knowledge of the author, though. The K: handler respects now the BREAK key correctly. ๐ŸŽ€


๐ŸŽ€ THE E: EDITOR

The editor device is much more decoupled from the screen handler than in the original ROM โ€” see also the S: handler section below.

๐Ÿ’– Editor Buzzer

The buzzer is run on a cursor position that depends on the editor margins now. It is also rung on character insertion if characters are likely to be moved out of the screen.

๐Ÿ’– Editor Window

Unlike the original Atari Editor device, the emulated E: handler allows arbitrary high editor windows โ€” not just four or 24 lines โ€” if programmed properly. main character energy tbh. โœจ

๐Ÿ’– Editor Scrolling

on line insertion or delection does no longer overwrite memory above MEMTOP. thank god honestly.


๐ŸŒˆ THE S: SCREEN HANDLER

As mentioned above, the S: handler is decoupled from the E: handler and therefore reacts in certain aspects differently than its original counterpart.

โญ Screen GET/PUT

The S: handler no longer tries to scroll, neither does it respect editor margins. If the put or get commands reach the end of the screen, an out-of-bounds error (error 141) is generated. The only control codes the screen handler handles separately are:

  • $7d, which clears the screen
  • $9b, which implements a line feed, though dos not scroll

โญ Open Command

The S: open provides more graphic modes than the original. If 64 is added to the graphics mode, then a text window is generated even for the graphic modes 9, 10 and 11. Unlike in the original Os, smooth scrolling works correctly in text windows, even in text windows of the GTIA modes 9 to 11. ๐Ÿ’…

โญ DMA/Player-Missile

The S: handler no longer interacts with player/missile graphics and respects the corresponding bits in the DMACTRL shadow register.

โญ Out of memory situations

will be handled more graceful than in the original ROM. ๐Ÿซถ


๐Ÿงš THE P: PRINTER HANDLER

The built-in ROM supports the printer to full extend, and no functional changes should hopefully appear. fingers crossed bestie. ๐Ÿคž


๐Ÿ”ฅ MATH PACK

The MathPack is not part of the operating system, but historically part of the BASIC. As a consequence, the math pack is does not provide a jump-in table as the operating system, and fixed ROM-addresses must be used.

Atari++ also provides an emulation, or rather a replacement implementing the same routines as the original math ROM. The precision and speed of the re-implementation should be superior to the original ROM implementation. However, it is, in general though, advisable to use the MathPackPatch, which is again a lot faster and still more precise than the re-implementation, because it uses the floating-point math of the host machine. ๐Ÿฆ‹

so like: replacement is good, MathPackPatch is better, and it's all floating-point-on-the-host-CPU flavoured. obsessed. โœจ
โš ๏ธ Real talk bestie: the author tried their absolute best to make this replacement math-pack match the original ROM, but some problems are lowkey expected. BASIC and MAC/65 software should be mostly unaffected, but Atari never gave anyone a jump-in table for the math-pack, so third-party software might be calling routines that were never officially documented and aren't provided by the emulation. That said, this math-pack replacement already contains a bunch of unofficial call-ins that BASIC and other software use. Ngl, numerical results from this implementation might differ from the original because of round-off stuff โ€” where the re-implementation often serves up better, more precise results. ๐Ÿ’…

The replacement math-pack provides the following routines and data:


AFP $d800

Okay so it converts the ATASCII number sitting in the buffer pointed to by "inbuff" ($f3,$f4) at the offset given by "cix" ($f2) into a floating point number in "fr0" ($d4 to $d9). โœจ On output, "cix" points at the first character that couldn't be converted. The carry register gets set if no conversion could be conformed at all. And unlike the original? This one operates at ten instead of nine-digits precision and rounds properly if you hand it more than ten digits. Iconic behavior honestly.

FASC $d8e6

Converts the floating point number in "fr0" ($d4 to $d9) into ATASCII in the output buffer at $580 and following. Heads up: "fr0" is destroyed on completion. ๐Ÿ’€ The end of the string gets flagged by setting the MSB of the last character, and the final string is pointed to by "inbuff" ($F3,$F4) on exit. Unlike the ROM implementation, this routine is more streamlined and does not overwrite bytes in front of the output buffer โ€” the output will always start at, and not sometimes in front of, $580. And if you call it at FASC+3, the user can define their own output buffer wherever they like by placing the address into "inbuff". That last part is not available in the original ROM, bestie.

IFP $d9aa

Converts the unsigned integer in "fr0"(lo) and "fr0+1"(hi) into a floating point representation in "fr0" ($d4 to $d9). And unlike in the original ROM, "IFP+4" converts the integer in the registers X(lo) and Y(hi) into floating point. ๐ŸŽ€

FPI $d9d2

Converts the floating point number in "fr0" ($d4 to $d9) into a two-byte integer representation, also in "fr0" and "fr0+1", rounded correctly to the nearest integer. If the conversion isn't possible, the carry bit gets set. The original implementation had a couple of issues with overflow and rounding โ€” those are not reproduced here, so we're good. ๐Ÿ™ˆ

ZFR0 $da44

Initializes the "fr0" register ($d4 to $d9) with zero. That's it, that's the vibe. โœจ

AF1 $da46

Initializes the six-byte floating point register pointed to by the X register with zero. ๐Ÿ’ซ

ZERORGS $da48

Clears N bytes starting at the zero-page register given by X, where N is given in the Y register. This inofficial call-in is used by Mac/65 and BASIC. ๐Ÿซถ

LOADOUTBUFF $da51

Initializes the "inbuff" zero page registers ($f3 and $f4) to point to the floating point output buffer at $580. Used by BASIC and MAC/65.

FADD $da66

Adds the contents of the floating point register "fr1" ($e0 to $e5) to the floating point register "fr0" ($d4 to $d9). "fr1" will be destroyed. Sets the carry in case the representation overflows, and destroyes "fr1". Unlike the orignal, this routine employes a correct "round to nearest" policy if the output cannot be represented exactly, and it also uses denormalized numbers if the output is very close to zero. ๐ŸŒธ

FSUB $da60

Subtracts the contents of the floating point register "fr1" ($e0 to $e5) from the floating point register "fr0" ($d4 to $d9). "fr1" will be destroyed. Otherwise, it works just like the floating point addition and its new round-to-nearest mode. ๐Ÿ’œ

FMUL $dadb

Multiplies the contents of "fr1" ($e0 to $e5) with "fr0" ($d4 to $d9) and places the result in "fr0". "fr1" will be destroyed. On overflow, the carry flag of the processor will be set. Like addition, this routine uses a smarter round-to-nearest policy, and unlike the original, it has all issues on detecting overflows fixed โ€” specifically, multiplying two very small numbers will give zero, not an overflow. It'll also handle denormalized numbers correctly, and it's noticably faster than the original. ๐Ÿ”ฅ

FDIV $db28

Divides the contents of "fr0" ($d4 to $d9) by the contents of "fr1" ($e0 to $e5) and places the result in "fr0", destroying "fr1". On overflow or divide by zero, the carry flag will be set. This routine also uses a precise round-to-nearest policy. Unlike the original routine, dividing a small number by a very large number will not create an overflow, but โ€” as appropriate โ€” zero. ๐Ÿ˜Œ

SKIPBLANKS $dba1

This routine is not officially documented but is nevertheless used by Mac/65. It skips all blank-characters in the input buffer ($f3,$f4) at the offset in "cix" ($f2) and adjusts "cix" such that it points at the first non-blank character. ๐Ÿ’…

TESTDIGIT $dbaf

Another inofficial function used by Mac/65 and BASIC. This one tests the character at "inbuff" ($f3,f4) at offset "cix" ($f2) for a valid decimal digit, and returns the numerical value of that digit with the carry flag cleared if possible. Otherwise, on an invalid digit, the carry flag gets set. โœจ

FR0TIMESTEN $dbeb

This is also an inofficial vector that multiplies the mantissa of the fr0 floating point register at address $d4 by ten โ€” i.e. it shifts all digits to the left. It's used by the multiplication and division function, and the Basic++ square root function. ๐ŸŽ€

NORMALIZE $dc00

This method is neither officially documented, but used nevertheless by BASIC and Mac/65. It normalizes the floating-point number in "fr0" ($d4 to $d9), eliminating leading zero-digit pairs in the mantissa and adjusting the exponent accordingly. It returns with the carry flag cleared on success and with the carry set on overflow. And unlike the original implemenation, this version leaves near-zero numbers denormalized, and overflows at a decimal exponent of 100, not at 99 as the original. ๐Ÿ‘‘

PLYEVL $dd40

Evaluates the polynomial whose floating point coefficients are pointed to by X(lo) and Y(hi) at the location given by "fr0" ($d4 to $d9). The number of coefficients โ€” and hence the degree of the polynomial plus one โ€” is passed in the accumulator on entry. Returns the result in "fr0", and destroys "fr1" ($e0 to $e5), sets the carry flag on overflow. ๐ŸŒˆ

FLD0R $dd89

Loads "fr0" ($d4 to $d9) with the floating point value pointed to by X(lo) and Y(hi).

FLD0P $dd8d

Loads "fr0" ($d4 to $d9) with the floating point value pointed to by "flptr" ($fc,$fd).

FLD1R $dd98

Loads "fr1" ($e0 to $e5) with the floating point value pointed to by X(lo) and Y(hi).

FLD1P $dd9c

Loads "fr1" ($e0 to $e5) with the floating point value pointed to by "flptr" ($fc,$fd).

FSTOR $dda7

Stores "fr0" ($d4 to $d9) to the six-byte memory buffer pointed to by X(lo) and Y(hi).

FSTOP $ddab

Stores "fr0" ($d4 to $d9) to the six-byte memory buffer pointed to by "flptr" ($fc,$fd).

FMOVE $ddb6

Copies the contents of "fr0" ($d4 t0 $d9) to "fr1" ($e0 to $e5). ๐Ÿฆ‹

EXP $ddc0

Computes a the exponential function at the location given by "fr0" ($d4 to $d9), destroys the contents of "fr1". Returns with the result in "fr0" and the carry cleared on success, with carry set on overflow. ๐Ÿ’–

EXP10 $ddcc

Computes 10 to the power of the number given in "fr0" ($d4 to $d9), destroys the contents of "fr1", returns with the carry set on overflow or the proper result in "fr0". This implementation isn't just faster than the original ROM implementation โ€” it's also more precise, and in general, nine to ten correct digits can be expected. It also has a couple of issues of the original implementation fixed, namely the exponential of a very negative number yields zero (not an overflow), and the exponential of ten to an integer power is always integer. โœจ

BASIC uses this function to compute the exponential via the call-in above, but also to compute the power function (a^b). Unfortunately, due to a bug in BASIC revisions B and C (but not in revision A), BASIC always rounds the result up to the next integer if a and b are integer โ€” with the side effect that if the result of this method is a tiny little bit too large, the output will be off by one. For example, computing 4^4 results in 256.000002, which is correct to nine places, but which is rounded by BASIC to 257. This is a bug in BASIC and not in this implementation โ€” the coefficients have been carefully choosen to avoid such situations for lower exponents, i.e. for b=1 to 3, the result will always be correct. Enforcing correct results for higher exponents would have resulted in a major precision loss just to work around old bugs, which was considered inappropriate. ๐Ÿ˜ค

FFRAC $de95

This is another call-in that is used by BASIC which is not officially documented. It computes the rational function (x-C)/(x+C) where the value of x is given by the contents of the "fr0" register ($d4 to $d9) and C is stored as a six-byte floating point number pointed to by X(lo) and Y(hi). On exit, the carry flag is set on overflow, and clear on success. Then, the result is given in the "fr0" register. ๐ŸŒธ

LOG $decd

Computes the natural logarithm of the number given in "fr0" ($d4 to $d9). Returns with the carry set on overflow, or zero or negative input โ€” otherwise with the result in "fr0". ๐Ÿ’œ

LOG10 $ded1

Computes the decadic logarithm (logarithm to the base of ten) of the number given in "fr0" ($d4 to $d9). Returns with the carry set on overflow, negative or zero input, and carry cleared with the proper result in "fr0" otherwise. This method can be expected to be faster and more precise than the original version. ๐Ÿ”ฅ

ONEHALF $df6c

okay so this one is not a call-in, bestie, it's a floating-point constant that BASIC uses for a bunch of stuff, most notably for the SQR function. Its value is 0.5. cute little half, slaying.

ATNCOEFF $dfae

also not a call-in! this is a table of eleven floating point constants, and they represent the coefficients of the minimax-approximation of the arcus tangens over the interval from 0 to 1. BASIC's implementation of the ATN function is the one that uses it. ๐Ÿ’…

NEARONE $dfea

part of that table up there, but BASIC also uses it on its own. it's the constant term of the above polynomial, and it also gets used to adjust coefficients outside the interval 0..1 by means of the functional equation of ATN. in an ideal infinite-precision implementation this constant should be exactly one, but because of various round-off errors it's 0.9999999999 in the Atari ROMs. in the emulated ROM, though, its value is 1.0 precisely. โœจ

PIOVER4 $dff0

another floating point constant used by BASIC โ€” this one is the value of Pi divided by four, correct to ten decimal places. it gets used by the ATN function in the BASIC rom. ๐Ÿฅง


๐ŸŽ€ THE D: HANDLER ๐ŸŽ€

so this handler comes from the now built-in FMS, the one that's used if disk-bootstrap was unsuccessful or got aborted by the user โ€” see also above, bestie. ๐Ÿ’–

the FMS sitting in ROM space is basically a reworked and bugfixed version of Dos 2.XL/XA by the same author, streamlined to fit into the low memory Os area 0xc002 to 0xcbff. that means it gives you 963 free sectors on a standard enhanced density disk while still keeping Dos 2.0S compatibility. and in specific? the VTOC layout is identical. no cap.

it can read Dos 2.5 disks, but it is not write-compatible to Dos 2.5. this route was chosen basically because the author had the Dos 2.XL sources available for obvious reasons, unlike the Dos 2.5 sources. anyway, the following documents the FMS command set:

CMD 3: OPEN

opens a file. the details depend on AUX1 and AUX2. for AUX1 = 0, the following modes are used:

  • aux1 = 4 โ€” open for read-only
  • aux1 = 6 โ€” open for directory reading, including the disk name
  • aux1 = 7 โ€” open the directory, excluding the disk name
  • aux1 = 8 โ€” create/overwrite for write-only
  • aux1 = 9 โ€” open for append write-only
  • aux1 = 12 โ€” open for read and write (update)
  • aux1 = 13 โ€” create for read, write and append

note that mode 9 does not waste a sector, unlike the Dos 2.0S implementation. mode 12 is the update mode, and it generates an EOF condition in case it's attempted to extend the file over its initial size. mode 13 is new and automatically extends the file over its boundary should a write past the EOF be sent. unlike mode 9, the file pointer is positioned at the start of the file initially. mode 6 also includes a disk title should it be provided.

for AUX2 = 128, things change dramatically. this mode provides full random access to the raw disk without any file management functions; so yeah, this mode allows โ€œrawโ€ access to disks. file names do not matter here as long as they are syntactically correct, and sectors are always 128 bytes long. the disk is understood as one big sequential file starting at sector one and extending to its last sector. access to sectors is provided by means of the POINT/NOTE commands. the following open modes are available for AUX1 = 128:

  • aux1 = 4 โ€” open for read-only. reads raw sectors sequentially
  • aux1 = 8 โ€” create for write-only. writes raw sectors.
  • aux1 = 12 โ€” open for simulateous raw read and write

CMD 5: GET RECORD

the standard CIO record reading command. reads bytes until the record is full or an EOL is detected. simple, iconic, no notes.

CMD 7: GET CHARACTERS

reads characters into the buffer until either the buffer is full or an EOF condition is reached. the FMS tries to bypass CIO here, i.e. it tries to โ€œburstโ€ to speed up processing. ๐Ÿƒโ™€๏ธ๐Ÿ’จ

CMD 9: PUT RECORD

writes bytes to the file/disk until either the buffer becomes empty, and EOL is found in the buffer or an EOF condition is generated.

CMD 11: PUT CHARACTERS

writes characters to the file until the buffer becomes empty or an EOF condition is generated. this command also implies bursting, if possible.

CMD 12: CLOSE

closes the file, writes the last buffer out and updates the directory โ€” unless the stream is โ€rawโ€œ.

CMD 13: STATUS

okay this one works a little bit different than under DOS 2.0S and DOS 2.5, where it only checks the validity of a file specification and the availability of a drive. since BASIC never supplies this information to STATUS, this command was actually unuseful in BASIC and never worked as intended. ๐Ÿ’€

instead, if the channel is already open, STATUS returns the status of the last CIO operation on this specific channel, which now allows BASIC to check, for example, whether the next GET command will return an EOF by testing against the error code 3. โœจ

if the channel is still closed, it works as it did for DOS 2.0S and DOS 2.5: it checks the given filespec for validity, tests wether the given disk is available and readable, and whether the file can be written to. otherwise, appropriate error conditions are generated. if used from BASIC, STATUS should then be rather replaced by a XIO 13 command which supplies a file name.

CMD 32: RENAME

renames files. requires the old filespec, then a comma, and the new target file name. this command may cause several identically named files. such files can be resolved by using the /1 through /9 file specification modifier defined below. alternatively, this command and the next four โ€” namely DELETE, FIND, LOCK and UNLOCK โ€” take a non-zero aux2 value which then specifies which of the specific matches to a wildcard is to be renamed, deleted, found, locked or unlocked.

CMD 33: DELETE

delete one or several files on the disk. bye bestie ๐Ÿ‘‹

CMD 34: FIND

resolves a wild card filespec and returns a full file name in the input buffer. this command is used by the command line interpreter (โ€œDUPโ€) to resolve wild-cards.

CMD 35: LOCK

prevents a file or several files from getting overwritten by setting their write-protecting bits. ๐Ÿ”’

CMD 36: UNLOCK

removes the write-protection lock on a file or several files. ๐Ÿ”“

CMD 37: POINT

places the file pointer at a given file/sector position. unfortunately, the FMS doesn't provide simple sequential accessing of files, but rather expects an absolute sector/byte offset in AUX3,AUX4 (sector) and AUX5 (byte), similar to Dos 2.0S.

โš ๏ธ if an invalid write position is specified here, then the disk might get corrupted. only file pointers obtained by a previous NOTE onto the same file should be passed in as arguments here. fr fr, be careful.

unlike under DOS 2.0S and DOS 2.5, POINT also works for files opened in write-only mode, i.e. mode 8, and can there be used to re-position the file pointer to some place in front of the EOF, overwriting data that has already been written. similarly, POINT is very helpful to append to files in the update/append mode 13 when the former EOF position has been recorded by a NOTE, which then works much faster than having the file opened in append mode. the latter has to find the EOF manually, the former will place the file pointer directly at the EOF.

the POINT command is also used for absolute positioning within the disk if the corresponding stream is opened for raw mode, i.e. with AUX2 = 128.

CMD 38: NOTE

returns the current file pointer as sector/byte offset to be used for a future POINT command. AUX3/4 contain the low/high-byte of the sector, AUX5 the sector offset.

CMD 39: INIT

clears and initializes the disk, erasing all files, but not formatting the disk. this is a quick format for disks that have been formatted already. optionally, a disk title can be given behind the device specification. this title will then appear in reverse video on each directory listing. โœจ

CMD 40: FIND

similar to CMD 34 to maintain Dos 2.XL compatibility.

CMD 41: BINARY LOAD

loads a binary file from disk, possibly initializing and running the binary. AUX2 specifies whether the loaded file shall be initialized or run:

  • 192 โ€” the file is initialized and run
  • 128 โ€” โ€œinit onlyโ€
  • 64 โ€” just runs, but does not initialize the file
  • 0 โ€” neither runs nor initializes the file

note that Atari specified CMD 41 (and not CMD 40) for the binary load command.

CMD 42: FORMAT

formats a disk in various sizes:

  • if AUX1 is set to 33, then the disk is formatted in single density to 707 sectors.
  • for AUX1 set to 34, then an enhanced density format is initiated, resulting in a 963 sector disk.
  • all other values are reserved.

this command also accepts a disk title.

CMD 43: FORMAT ENHANCED

initiates a standard enhanced density format, independent of AUX1 and AUX2. this also accepts a disk name, similar to the above.

CMD 254: FORMAT ENHANCED

identical to CMD 43. literally the same thing, no notes. ๐Ÿ’…


๐ŸŒธ FMS FILE SPECS ๐ŸŒธ

the built-in FMS defines the following rules for filenames; these rules are very close to those formulated by Dos 2.0S.

  • the first character must be an uppercase letter, and all remaining characters must be uppercase letters or digits.
  • a file name consists of at most eight characters, and an optional three character extender behind a dot (โ€œ.โ€).
  • three wild card-characters are understood:
    • the question mark โ€œ?โ€ โ€” matches one single arbitrary character
    • the asterisk โ€œ*โ€ โ€” matches a sequence of arbitrary characters except the dot
    • the dash โ€œ-โ€ โ€” equivalent to the wild-card sequence โ€œ*.*โ€ and thus matches any file

...and bestie, there's MORE. The FMS also lets you tack on access mode modifiers to a file name to change what a command actually does. You stick them on behind a slash, /, like this: D:FILE/A. Here's the whole menu of them:

  • /A โ€” opens a file in append mode instead of write mode, so it flips mode 8 โ†’ mode 9. It also switches plain directory mode over to the restricted directory mode that suppresses the disk name, and turns mode 12 into mode 13. Every other combo? Invalid, sorry. This one slaps in the FMS command line next to COPY when you wanna append one file onto another. ๐Ÿ’…
  • /D โ€” flips the open mode from reading to directory reading, i.e. mode 4 โ†’ mode 6. Super handy in the FMS command line for printing the directory via COPY D:-/D,P:.
  • /O โ€” doesn't touch the open mode at all, it just turns OFF verify writes and uses the faster write-without-verify disk command. Faster writes, but the tradeoff is it might hide write errors on janky disks. ๐Ÿซฃ
  • /V โ€” basically the same energy as above, except it enables verify writes.
  • /N โ€” only matters with the BINARY LOAD command, and it stops the program from launching right after it loads.
  • /1../9 โ€” if you've got several identically named files, this grabs the n-th one. Perfect for picking between files that the Rename command left with the same name. ๐ŸŽ€
Ngl, the file spec DOS.SYS is not special to the FMS at all โ€” unlike DOS 2.0S. It's just a regular file, fr fr. The FMS will never ever try to write itself to disk. So even though the FMS can write a Dos 2.XL disk structure just fine on initialization, those disks won't be bootable without the ROM FMS.

๐Ÿ’€ FMS ERROR CODES ๐Ÿ’€

The FMS throws these error codes. (Generic SIO errors aren't listed here because those come from the Os kernel, not the FMS.)

  • Error 160, IllegalUnit โ€” the disk unit you asked for isn't available.
  • Error 161, TooManyFiles โ€” too many files open at once, the FMS ran out of buffers.
  • Error 162, DiskFull โ€” no more free space on the disk, bestie.
  • Error 164, FileLinkBroken โ€” the FMS structure is damaged, possibly from an invalid POINT.
  • Error 165, FileNameInvalid โ€” that file name is invalid.
  • Error 166, InvalidPoint โ€” an argument to POINT was out of range.
  • Error 167, FileProtected โ€” you tried to write to a locked file. Not today. ๐Ÿ”’
  • Error 169, DirectoryFull โ€” couldn't create the file because the directory was full.
  • Error 170, FileNotFound โ€” the filespec you gave doesn't exist.
  • Error 175, NoBinaryFile โ€” the file you specified isn't a binary load file.
  • Error 176, BadLinkage โ€” found a bad sector link pointing to sector #0, meaning the disk structure is damaged.
  • Error 177, InvalidMode โ€” the open mode you specified is invalid.
  • Error 178, NotADosDisk โ€” the structure of the inserted disk isn't compatible with Dos 2.++.

โœจ THE COMMAND LINE PROCESSOR (DUP) โœจ

The built-in FMS also ships a whole disk utility package โ€” a "DUP" ๐ŸŽ€. You fire it up from BASIC with the DOS command, or it just runs automatically if no cart is found inserted.

The command line takes commands kinda like a Linux shell, except way more restrictive. If what you typed is just a device spec โ€” a one- or two-letter string ending in a colon โ€” then the active device changes. Otherwise the command line goes hunting for the command as a file on disk, as a binary, and runs it. It does NOT append a file extender, unlike OS/A+ which would always slap .COM on there. The file name is loaded and executed exactly as you entered it. ๐Ÿ‘‘

The full command line, command + arguments, gets dropped into a 128 byte buffer at $580 where the executed binary can find it and parse it itself if it wants. The command line doesn't give you any functions to parse that buffer though.

NOTE: this is not how Dos OS/A+ runs external commands. There just wasn't enough ROM space to implement command line parsing service functions like OS/A+ has. ๐Ÿ˜ญ

If the command starts with a double quote, or isn't found on disk, the command line processor tries to find it as an internal command. Here's the lineup. Optional arguments are shown in square brackets โ€” those brackets are not part of the actual command syntax, just so you know. And filespec means a file specification, optionally with wildcards, optionally with a device spec separated from the file name by a colon. No device name given? Then it uses the currently active device that's sitting in front of the command.

  • DIR [filespec] โ€” lists the disk directory. Give it a filespec and only the files matching that filespec get listed. DIR can't list the directory to any other device though. For that, use the COPY command with a source filespec carrying the /D access modifier.
  • DELETE filespec โ€” deletes the file(s) matching the filespec. Heads up: this one does its job immediately with zero follow-up questions. ๐Ÿ’€
  • RENAME filespec,newname โ€” renames a file, or several files, to a target filename on the same device. If more than one file matches the wildcard, they ALL get renamed to the same target name. You can pick between identically named files using the /1 to /9 modifiers, which lets you rename some of them back. ๐Ÿฆ‹
  • LOCK filespec โ€” marks the file(s) as write-protected. After that, any kind of write operation or deletion is prohibited.
  • UNLOCK filespec โ€” removes the write protection again. Literally the opposite of the above.
  • CAR โ€” runs the cartridge, if there is one inserted. If there's no cart available and no reset resident program found either, the command processor gets entered again.
  • FORMAT [title] โ€” formats the specified disk to enhanced density, erasing all its contents. You can throw in an optional disk name here that'll be printed in inverse video when listing the directory contents. ๐ŸŒˆ
  • CLEAR [title] โ€” similar to the above, clears the entire disk contents and installs an optional disk name. BUT CLEAR only re-initializes an already formatted disk. Because of that, CLEAR is way faster than FORMAT โ€” it's meant as a quick-format. โšก
  • RUN [hexaddress] โ€” runs a machine code program at the specified address. No address given? Then the previously loaded command gets run, or run again.
  • SAVE filespec,from,to,[[,init],run] โ€” saves a binary file to disk, starting at the given hex address and going up to the given address. You can optionally give an init and run address too. Oh and btw, you can always append to a file โ€” and thus extend a binary load file โ€” using the /A access modifier behind the file name. ๐Ÿ’–
  • LOAD filespec โ€” loads a file from disk but doesn't start it. You can run it later with the RUN command, no extra arguments needed.
  • COPY filespec,target โ€” copies one or several files from one disk to the same or another disk. COPY first reads the file from the source, then waits for you to swap disks. If source and target are the same disk, just hit RETURN; otherwise swap disks first. Then COPY writes the target file, and might ask you to re-insert the source disk if the file's too big to read in one go, or if there's more than one file to copy. ๐Ÿ”„

COPY tries to avoid using user RAM contents whenever it can. Application memory that's correctly reserved by setting the Os vector APPMEMHI will be preserved, and BASIC source code will be spared. But not every app sets APPMEMHI correctly โ€” Mac/65 is one such example. ๐Ÿ™ˆ

  • NEW โ€” erases user memory and makes that memory available to the COPY command, meaning you'll need to swap disks less often. NEW is also needed to tell some cartridges or application programs that their memory has been overwritten after a copy operation. That's necessary when the program in question doesn't set APPMEMHI correctly.

๐ŸŒธ FMS HINTS AND TWEAKS ๐ŸŒธ

Sometimes an external command has the same name as an internal one. When that happens, the external command wins โ€” it gets loaded and the internal one is bypassed. If that's not what you want, put a double quote in front of the command. That skips the external command lookup. ๐Ÿ’…

You might've clocked that DIR can't list the directory to anything but the screen. Well, COPY can pull off a similar move using the /D access specifier:

COPY -/D,P:

That prints the contents of the directory by copying it to the printer device โ€” though it invalidates RAM contents, because of the extra buffering COPY does. ๐Ÿ˜ฌ

And you can emulate the LOAD command using the no-run specifier when you just wanna load, not run, an external command. So LOAD foobar and foobar/N are equivalent. โœจ


๐Ÿ‘‘ FMS BOOTSTRAP PROCESS ๐Ÿ‘‘

If the FMS gets initiated by the built-in Os, and a disk is found active and usable, these extra bootstrap steps go down:

  • FMS Configuration โ€” the FMS tries to load and execute the binary load file D:CONFIG.SYS. This file should modify the FMS settings by writing into its configuration area. The FMS then re-allocates buffers according to its new settings. And note: this is the only way to modify FMS parameters, since the FMS is ROM based. ๐Ÿ”ฅ
  • Handler bootstrap โ€” next, the FMS tries to load and execute the binary file D:HANDLERS.SYS. This file should contain the bootstrap code for any additional boot-time handlers that need to be linked into the system. For example, it could load and run the 850 interface box firmware โ€” easiest by just calling the Os vector BOOT850, $e48f. ๐Ÿงš
  • Command execution โ€” last, the FMS runs the traditional D:AUTORUN.SYS file. This is a user-defined binary load file that could contain basically anything the user wants. ๐Ÿ’œ

๐ŸŒธ OS EQUATES ๐ŸŒธ

okay so the built-in Os is lowkey matching the Atari 800XL ROM's memory map almost beat for beat, with just a few lil glow-ups added. ๐Ÿ’… Heads up bestie: those memory cells the XL operating system set aside for parallel port and tape stuff? They're probably not doing anything anymore. But they stay reserved, fr fr โ€” future versions of the Atari++ operating system might want them back. ๐Ÿ‘‘

  • $15 FMSTMP โ€” the FMS uses this for, like, various issues. โœจ
  • $16 DIRENTRYOFFSET โ€” the FMS uses this to point into the directory buffer for whichever file it's currently processing.
  • $1a FILECOUNTER โ€” when a wildcard matches a whole bunch of files and you hit it with a /1 to /9 access modifier to pick one, this location records your pick. If the FMS should operate on all the matches, this location just stays at $ff.
  • $1b FREEDIRCODE โ€” keeps the file number times four of the first free directory entry that a new file could move into.
  • $43 FMSPTR โ€” temporary pointer variables for miscellaneous FMS business. This pointer typically points at the directory entry of the file currently being processed.
  • $45 DISKBUFFER โ€” points, inside the FMS, to the VTOC buffer for the disk drive currently being processed.
  • $47 FILEBUFFER โ€” points, inside the FMS, to the file input/output buffer for the file currently being processed.
  • $24e VECNMI โ€” the Os jumps through this vector when it detects an interrupt on ANTIC's NMI-input pin. That pin is routed to the RESET key on the 400 and 800 machines, and it's just open on the XL and later machines.
  • $2b8 OVERRUNFLAG โ€” the E: handler sets this flag when the line is nearly full and the buzzer should run. ๐Ÿ””
  • $318 SCREENSTACK โ€” traditionally SIO's byte, and the built-in Os does the same. It's also used by the S: and E: handlers to keep the stack pointer around so error handling is easier. ๐Ÿซถ
  • $3f5 FMSBOOTFLAG โ€” specifies the FMS bootstrap modes plus a bunch of other related stuff, as listed right here:
    • Bit 0 โ€” if set, the next reset shall signal the cart a coldstart. The command line processor sets this bit when the memory contents get invalidated by the COPY command.
    • Bit 4 โ€” if set, the FMS places MEMLO at the end of its globals instead of at the end of the FMS buffers. User programs โ€” most notably a CONFIG.SYS file โ€” may relocate FMS buffers elsewhere and can then choose to set this bit. Never set by the FMS itself.
    • Bit 6 โ€” set if the command processor shall be launched on the next warmstart.
    • Bit 7 โ€” set if the FMS should be initialized on Reset. Note that the FMS no longer requires the DosInit vector.
  • $3f6,$3f7 DUPVECTOR โ€” DupVector (hi). This address gets jumped to instead of the cart run vector during a warmstart, if bit 6 of the FmsBootFlag is set. A program that jumps through DOSVECTOR ($a,$b) will set bit 6 of the FMSBOOTFLAG, then cause a reset, which in turn runs the command processor through this vector.

The next addresses are only used if the FMS is initialized. They can be modified from the CONFIG.SYS file to change the FMS parameters when booting. ๐Ÿ‘‘

  • $70a FMSDRIVEMASK โ€” contains a bitmask defining which drives should be addressable. A one-bit enables the corresponding disk unit, a zero disables it. Bit #0 enables/disables drive 1, bit #1 controls drive 2, and so on. The default value is 3, meaning a two-disk system is supported. Each supported drive requires 128 bytes of additional storage.
  • $709 FMSBUFFERS โ€” the number of file buffers the FMS shall allocate. This controls how many files can be opened at once. The default value is five, so you can open at most five files at once. Each file buffer requires 128 bytes of storage.
  • $779 WRITECMD โ€” the SIO command the FMS shall use for writing sectors. This can be either $50 ("P") for writing without verify, or $57 ("W") for writing with verify. It is however suggested to use the file name extenders "/V" and "/O" to switch between verify on and off instead.
  • $70C,$70D DISKBUFFERBASE โ€” points to the first disk buffer used by the FMS. The "CONFIG.SYS" file may change this base address to point elsewhere, in which case disk buffers will be allocated from this memory address on. If in addition bit 4 of FMSBOOTFLAG is set, the FMS init routine will neither try to increase MEMLO to point behind the FMS buffers, but will keep it at the end of its state flags.
  • $712,$713 FILEBUFFERBASE โ€” this pair points to the first file data buffer within the disk buffers. It cannot be adjusted, but is always allocated by the FMS.
  • $700 to $7ff FMS STATE FLAGS โ€” addresses $700-$7ff except those above contain FMS state variables that remain undocumented. ๐Ÿคซ
  • $800 FMS BUFFERS โ€” FMS buffers for drives and file buffers are allocated from $800 up. In the default configuration, they extend up to $a7f, leaving RAM from $a80 and up to the user. So the memory footprint of the built-in FMS is much better than for DOS 2.0S. FMS buffers may be relocated by adjusting DISKBUFFERBASE accordingly, via a suitable CONFIG.SYS file.

๐Ÿ’– THE BASIC EMULATION ๐Ÿ’–

Atari++ includes an emulated Basic ROM, in case an original Atari Basic ROM image is not available. The Basic dialect emulated here closely reassembles the Atari Basic dialect and is to a major degree compatible with it. โœจ

Basic++ is, however, quite a bit faster thanks to smarter stack and branch handling, it is heavily bug-fixed, and slightly extended: ๐Ÿฆ‹

  • DIR [filenspec] โ€” this statement lists the directory of the given drive, looking for the files that match the file specification in its argument. For example,
DIR "D2:*.*"

will list all files on the second disk drive. If no filename is given, DIR will list all files on the first disk. The DIR command is compatible both in its syntax and its internal encoding to the same TurboBasic command.

  • LIST [filespec,][firstline[,[lastline]] โ€” a second notable extension is that the โ€œlastlineโ€ argument of the list statement can be dropped while keeping the comma upfront. This instructs LIST to start listing at the line given by the first argument, but continue up to the end of the program. This extension is identical to the extension of LIST in TurboBasic. For example,
LIST 1000,

will list all lines starting from line 1000 up to the last line.

The remaining extensions are minor and consist mostly of bug-fixes, speed improvements and improvements of the numerical accuracy of the floating point model. They are described in more detail in the Basic++ manual. ๐Ÿ“–


๐Ÿ‘‘ THE BUILT-IN MONITOR ๐Ÿ‘‘

Atari++ comes with a build-in mini-monitor that can be helpful for debugging programs, or for finding bugs in the emulator. The following section describes briefly the front-end and the commands of this monitor, assuming that the emulator has been compiled with curses support. Otherwise, the front-end is less user-friendly (or even more user un-friendly than it used to be before, but that is another topic). ๐Ÿ’€

๐ŸŽ€ ENTERING THE MONITOR ๐ŸŽ€

You enter the monitor either by pressing F12 while the emulation is active, by pressing ^C in the shell that launched Atari++, or if the CPU core emulator crashes. That crash could be either due to an instruction that is not implemented, an instruction that would otherwise stop the CPU completely, or an unstable instruction whose function depends on some floating bus signals that are hard or not at all emulatable. Other than that, Atari++ emulates all known stable โ€œextra opcodes some lesser quality programs tend to use. ๐Ÿ˜ญ

Another way of entering the monitor is by hitting a break point, or by finishing a single-stepped instruction. ๐Ÿซถ

๐ŸŒˆ MONITOR COMMANDS ๐ŸŒˆ

The monitor is entirely command line driven. Commands are four characters long, non-case sensitive, with a possible abbreviation of one character. Commands furthermore have an optional extension given by a dot (.) and a single additional character. This extender typically modifies the command somewhat, or sets some parameter for the command, as for example the output format. The extender for each command is remembered by the command itself up to the next time the very same command is used. Hence, you won't need to type the same extender every time. Using the question mark "?" as extender lists the available extenders for the command. ๐Ÿ”

Most commands also remember the last address they operated on. If typed without arguments, they silently re-use the last address used. This is handy for disassembling long routines, since you just have to re-type the disassembly command to continue the listing. โญ

๐Ÿงš ALGEBRAIC EXPRESSIONS ๐Ÿงš

The monitor is capable of evaluating simple algebraic expressions in C syntax containing the basic operators +,-,*,/, the binary operators &,|,^,~, the logical operators ||,&&,! , the comparisons <,<=,>=,==,!= and the shifts <<,>>. The precedence of the operators follows mainly the C syntax, except that priority of the shifts has been โ€œfixedโ€ to follow more closely the (or at least my) intuition, brackets are supported with their obvious meaning. Furthermore, the contents of the registers are available as the algebraic expressions A,X,Y,P,S,PC. Otherwise, numerical constants are understood in hex (sedecimal) notation. ๐Ÿ’…

If a ca65 debug file is loaded (see ENVI.S below), then labels or equates can also be used in expressions; they are then substituted by the value they have been assigned to in the debug file. ๐Ÿ‘‘

A nice gymmick are the indirection operators [],[].b,[].w with the first two being equivalent. They evaluate their contents as an address, and then return the contents of this (emulator) address as their value. The first two are byte versions reading a single byte, the latter is a word version that reads two bytes in little-endian notation to form a sixteen bit integer. ๐Ÿฆ‹

๐Ÿ’œ COMMAND DESCRIPTION ๐Ÿ’œ

The following commands are available in the monitor:

  • HELP=? โ€” this command prints a command summary. ๐Ÿ“‹

๐Ÿ‘‘ DUMP=D [expr] โ€” extenders: A, S, V

Dumps the memory contents at the address you hand it, or just keeps going from wherever the last dump stopped. Bestie it's literally the "show me the bytes" button ๐Ÿ’–

  • A โ€” switches to mixed hex-ATASCII output, emulating inverse video as much as it possibly can thru curses โœจ
  • S โ€” uses hex-ANTIC screen code dumps
  • V โ€” doesn't dump anything at all, it's just here to set the number of lines dumped in one go

โœ๏ธ EDIT=E [expr] โ€” extenders: X, D, A, S, I

Edits memory starting at the given address, in hex, decimal, ATASCII or Antic Screen codes respectively. Pick your flavour ๐ŸŽ€

For hex and decimal input, memory contents are lines separated by blanks, and the input is aborted by an empty line โ€” i.e. by just pressing RETURN. No drama, just vibes.

For ATASCII and screen code editing, the text you type as input gets placed directly into the memory of the Atari, possibly first converting to the target format.

  • I โ€” doesn't edit any memory at all, it just toggles the seventh bit of the ATASCII resp. screen code entries on or off ๐Ÿ”ฅ

๐Ÿง FILL=L addr size โ€” extenders: X, D, A, S, I

Fills the given memory range โ€” base address plus size, that's the whole vibe โ€” with a byte pattern. You'll get prompted for the fill pattern separately in a second stage, so don't panic:

  • X โ€” byte pattern is given as a space-separated list of hexadecimal (sedecimal) byte values
  • D โ€” the pattern is given in decimal notation instead
  • A โ€” lets you enter the bytes as ATASCII codes
  • S โ€” last but not least, encodes the pattern in the ANTIC screen codes

The I extender toggles the seventh bit of the entered ATASCII or screen code pattern on or off. Its setting is ignored for hex or decimal input, so don't even worry about it there ๐Ÿ’…


๐Ÿšš MOVE=M from to size โ€” extenders: S, C, A

Moves a memory block of the given size from the start location to the target location. Source and target may overlap โ€” and no cap, the move command is smart enough to copy memory blocks correctly in all circumstances ๐Ÿซถ

  • S โ€” performs a simple memory copy operation within the current address space, no matter which one has been selected by the ENVI command (see below)
  • C โ€” moves bytes from the selected address space into the address space as seen from the 6502. This is how you copy data from the ANTIC space to the CPU space โœจ
  • A โ€” works in the reverse direction by always writing into the ANTIC space

๐Ÿ” FIND=F [expr] โ€” extenders: X, D, A, S, I, V

Scans the memory starting at the given location for a byte pattern, possibly filtering that pattern thru a mask. You get prompted first for the byte string to look for, then for a possible mask โ€” which must either be left blank or be exactly as long as the pattern you entered first. If you leave it blank, the byte string in memory has to match precisely. Otherwise, only the one-bits in the mask are significant, and all zero bits in the mask are not compared against the search pattern.

This lets you do things like scanning for text in non-case-sensitive mode: just set all pattern bytes to 5F for ignoring case and inverse video bits. Iconic behaviour honestly ๐Ÿ˜Œ

The extenders work similar to the extenders of the EDIT or FILL commands:

  • X โ€” expects hexadecimal input
  • D โ€” requests decimal input
  • A โ€” allows ATASCII patterns
  • S โ€” screen code patterns

The pattern mask, however, is always given in hexadecimal notation. As always, the I extender toggles the seventh bit on or off for the A and S extenders. Last but not least, the V extender defines the maximal number of matches that will be printed before the search is aborted ๐ŸŒธ


๐Ÿงฎ EVAL== expr โ€” takes no extenders

Evaluates its argument and prints the result on the screen. Math girlies rise up ๐Ÿ’œ


๐Ÿชœ SKTB=K [expr]

Prints a stack traceback, optionally starting at the given stack address. For this option, the monitor will find the locations from which the current routine has been called. The locations of the JSR instructions are printed on the screen ๐Ÿฆ‹


๐Ÿ›‘ BRKP=B [expr] โ€” extenders: S, C, D, E, A, L, V, W

Controls breakpoints. Once a breakpoint is hit, and the breakpoint is enabled, the monitor is re-entered. Breakpoints can be set in either RAM or ROM. They do not alter the memory at all โ€” they're rather emulated directly in the CPU core. Hence, they cannot interact with software reading or interpreting the code. Sneaky in the best way ๐Ÿ’…

  • BRKP.S โ€” installs and activates a breakpoint at the address given by its argument
  • BRKP.C โ€” removes it again
  • D โ€” disables breakpoints that have been set before
  • E โ€” enables breakpoints that have been set before

A disabled breakpoint is temporarily turned off, but remembered, and can be turned on later on. No thoughts, just stored state โœจ

  • V and W โ€” install watch points. Unlike regular break points, the trapping condition is not execution of an instruction at a specific location, but the access of a specific memory address ๐Ÿ‘€
  • BRKP.W โ€” installs a watch point, i.e. the monitor is entered as soon as a program tries to write to the target address. Reading does not trigger it. Watch points can be disabled and removed as all other break points.
  • BRKP.V โ€” installs a read/write watch point that, unlike the above, also reacts on read accesses to its target address.
  • A โ€” removes all breakpoints at once
  • L โ€” lists all breakpoints and their status, i.e. whether they are disabled or enabled

๐Ÿ“บ DLST=A [expr] โ€” extenders: L, S, V

Displays the antic Display List and the ANTIC status.

  • L โ€” prints a disassembly of the ANTIC program, or short the Display List. Useful for getting an idea how the screen is generated ๐ŸŽ€
  • S โ€” prints the contents of the ANTIC register set, for example to find the start address of the display list
  • V โ€” sets the number of lines the ANTIC disassembler prints in one go

๐Ÿ”ง UNAS=U [expr] โ€” extenders: L, V

This is the 6502 disassembler.

  • L โ€” does exactly this: it disassembles at the address given by its argument. The disassembler knows all "extra instructions" of the 6502 and prints them as four character rather than three character opcodes ๐Ÿ‘‘

If a ca65 debug file has been (see ENVI.S below), then the disassembler automatically substitutes numeric values with the constants, labels and equates recorded in the debug file. Fancy fr fr ๐Ÿ’–

  • V โ€” sets the number of lines the disassembler prints at a time

๐Ÿ”„ RSET=P โ€” extenders: W, C, I

Various reset commands.

  • W โ€” warm-starts the emulator
  • C โ€” runs into a coldstart

Both instructions also leave the monitor, as its full working environment is reset as well. If you need to debug instructions directly following the cold-start sequence, consider using the -traceonreset on command line switch ๐Ÿ‘€

Note that the warm-reset really holds the reset signal of the CPU. This is unlike the Reset Console Key on the Atari 800 and 400 models work; they just raise a special Antic NMI signal and leave it to the Os to detect this signal and jump to the reset vector. This kind of reset is reached with the I extender, though note that the detection of this NMI interrupt has been removed in Os ROM of the XL and XE models.

๐Ÿšช EXIT=X โ€” no extenders

Takes no arguments and no extenders and leaves the emulator immediately. Bye bestie ๐Ÿ˜ญ๐Ÿ’จ


โ–ถ๏ธ GOPG=G โ€” extenders: P, U, M

Takes no arguments and re-starts the emulation at the current program counter value for the P extender. Hence, this leaves the monitor and continues emulation. Let's goooo ๐Ÿ”ฅ

  • M โ€” the emulation also continues, but the configuration menu is entered as soon as possible after leaving the monitor, as if F1 has been pressed. This may take as long as a vertical retrace of the emulated screen, and some code might have been run when the menu is entered.
  • U โ€” runs the program until the stack pointer gets larger than its current value. Useful to terminate a current subroutine call and return to the calling function immediately ๐ŸŒˆ

๐Ÿ‘Ÿ STEP=Z โ€” extenders: S, I

Single step thru a program.

  • S โ€” the simple interface is used and, similar to the GOPG command, the program is run, but the monitor is re-entered immediately after execution of the command under the PC, printing the command that was executed last. Most useful for debugging purposes and single-stepping thru critical sections of a program ๐Ÿ’…
  • I โ€” a full-screen graphical debugger is entered, provided the curses library was available at compile time. If so, a full screen of disassembled code is printed and the monitor waits for further commands. The Z key single steps then, the N key works similar to the NEXT command (see below) and steps over subroutines and loops, the G key re-starts the program and leaves the monitor, the B key sets a break point at the current program location and, finally, the U command runs the emulated CPU until the stack pointer is increased, thus usually up to the end of the current sub-program ๐Ÿฆ‹

โญ๏ธ NEXT=N โ€” no extenders

Similar to STEP though this command does not step into subroutines. For any operation that places data onto the hardware stack, this command will run the program up to the location where the data is again popped from the stack; if the current instruction is not a JSR instruction, then the emulator is run until the program counter of the emulated CPU gets larger than its current value. This is for example useful to complete a larger loop with a backwards branch at its end by just one monitor command. One command, whole loop handled, we love efficiency โœจ


๐Ÿ“Š STAT=T [comp] โ€” extenders: L, S

Prints status information about various system components, including internal hardware register sets, port settings and configuration.

  • L โ€” lists all system components for which a status information is available
  • S โ€” STAT.S followed by the name of this component prints the status of the mentioned component ๐Ÿ’œ

  • SETR=S register=expr โ€” no extenders, bestie. This one yeets a value into a CPU register, and the value comes from an expression. The syntax is lowkey non-standard because it's meant to be convenient: the register and the thing you want in it are separated by an equals sign, NOT by a blank. So for example SETR A=ff would set the contents of the accumulator to 255=0xff. ๐Ÿ’…
  • REGS=R โ€” no extenders. Shows you what's inside the CPU in a cute little brief listing. And honestly? This command is ideal for the SPLT command we're about to talk about. Iconic combo fr fr. โœจ
  • SPLT=/ [cmds] โ€” extenders: C, S. Okay so this command is special-special, because it doesn't actually do a direct thing to the emulation components โ€” it modifies how the monitor itself behaves. The S extender splits off the top part of the monitor output window and prints the output of whatever commands follow the SPLT command up there. Example: SPLT.S R would continuously display the register dump of the 6502 CPU on top of the screen. ๐Ÿฆ‹

You can run several commands at once by separating them with a colon. The split-off output gets updated on every command, which makes screen splitting literally the perfect feature for single stepping and debugging. The C extender cleans and removes that split-off part of the screen again. Bye bestie ๐Ÿ‘‹

  • ENVI=V [value] โ€” extenders: A, L, S, C. This controls various (currently one) monitor environment settings. Let's break it down: ๐ŸŽ€
    • A โ€” this extender controls the view onto the memory. Since the 130XE offers 128K of memory that can be selectively banked for the CPU and for ANTIC, it matters whether the memory is seen by the CPU or by ANTIC, because both may have selected different banks for it. This environment switch toggles the monitor's view onto the memory as either coming from ANTIC or from the CPU.
    • L โ€” this extender expects a file name as its argument. The status of the emulated CPU then gets logged into that file, including the register set and the timing information, i.e. horizontal and vertical beam position. โš ๏ธ Heads up: this file may grow very fast and becomes huge shortly. To disable logging, supply an empty file name.
    • S โ€” this extender loads a debug file into the monitor, which defines labels, equates and constants. This info gets used by the disassembler and the expression evaluator; the former substitutes numerical values by their label names and hence makes the output of the disassembler more readable, the latter also accepts labels and equates as input and replaces them by their value. This environment setting accepts files in the "debugfile" format generated by the ca65 assembler. They are created with the --dbgfile command line option of the assembler. The ENVI.S command takes a single argument, namely the file name of the debug file to be parsed. Information in this file is then added to the internal label database of the monitor. ๐Ÿ“š
    • C โ€” this extender clears the internal label database, i.e. it forgets all label, equate and constant names that have been defined by an ENVI.S command before. Memory wipe, but make it monitor edition. ๐Ÿงš
  • PROF=O โ€” extenders: S, L, C, X. This monitor command controls the built-in profiler, letting you find performance bottlenecks in machine language programs running on the emulated 6502. ๐Ÿ”ฅ
    • S โ€” starts recording profile information. After issuing this command, return to the emulator with GOPG and start and/or continue execution of the program you want to profile. Re-enter the monitor any time you want to access the collected profile data.
    • L โ€” lists the execution counts per memory, sorted in descending order. The first column of the profiler output lists the memory location, in hex or symbolic form, at which the profiled instruction was recorded. The next column shows the absolute count of how often that location was accessed. The last column lists the percentage of how often the listed instruction has been executed compared to the overall instruction count collected by the profiler. If several consecutive instructions have exactly the same hit-count, these instructions are not listed separately โ€” only the first instruction of the instruction block is shown. Note that this command extender lists instruction hit counts, i.e. it performs a coverage analysis, and not a cycle count analysis. ๐Ÿ‘‘
    • C โ€” lists the cumulative execution time of subroutines in cycles, listed in descending frequencies. Unlike the output of the L extender, this list shows the total number of cycles the CPU required to execute a subroutine, together with all the children it called. It sorts the output by cycle count, with the function taking the longest time on top. This is typically the main program. The percentage of time the code spent in a subroutine is also shown.
    • X โ€” this extender stops the profiler and clears the profiler database. Rip profiler data, you served well ๐Ÿ’€

๐Ÿ“ FILES ๐Ÿ“

  • /etc/atari++/atari++.conf โ€” The system global configuration files
  • ~/.atari++.conf โ€” The user specific configuration file
  • ./.atari++.conf โ€” The directory specific configuration file.

๐ŸŒˆ ENVIRONMENT VARIABLES ๐ŸŒˆ

No emulator specific variables. Atari++ is controlled completely by its configuration files and command line arguments. That's it, that's the whole section, no cap. ๐Ÿ’œ


๐Ÿ’– CREDITS ๐Ÿ’–

Shoutout time, because none of this happened alone:

  • David Firth for his Atari800 emulator. Atari++ is not based on this earlier work, though influenced. Atari++ was entirely and completely rewritten from scratch, in C++, avoiding some of the constructional difficulties of David's work. Especially, the way how graphics output is constructed and how player/missile graphic priorities are generated is quite different from his implementation.
  • Ron Fries for the Pokey emulation routine that got used in early releases of the Atari800 emulator. The strategy that has been utilized for sound build-up has been used in the pokey emulation of this emulator as well, though the implementation details are a bit different and the overall quality of the sound emulation has been improved heavily. Specifically, high-pass filters, sound muting and anti-aliasing are new to the emulation model. ๐Ÿ”Š
  • Jean-loup Gailly and Mark Adler for the Z compression library that gets used if available for .gz compressed disk images.
  • Sam Lantinga and the SDL group for the Simple DirectMedia Layer library, or short, SDL, that offers one of the possible front-ends of the Atari++ emulator if it is available.
  • Jindroush and the Atari Cartridge Dumping project for providing insight into the details of the cart emulation. Specifically, SDX and XEGS cart emulation would have been impossible without him. ๐ŸŽฎ
  • Petr Stehlik and the remaining atari800 team for cooperation and for working out the licencing conditions of this emulator. Specifically, I thank Petr for keeping cool in the hot days of working out all the details of making this project available.
  • Andreas Magenheimer and the ABBUC team for providing some hardware insight that was otherwise not available. Specifically, emulation of various bank switching logics is due to ABBUC.
  • Jason Duerstock's for its analyzation of the RT8 cartridge. Unfortunately, something seems to be still not quite right with it. The current implementation in Atari++ uses a somewhat different route how the register assignment might work. This is all an educated guess, though. ๐Ÿ™ˆ
  • B. Watson for keeping pushing me to re-implement the math-pack; it's been done, now, providing a full free implementation of the Atari operating system. โœจ
  • Konrad Kokoszkiewicz for finding and fixing many bugs in the emulation of floppy disks. Part of the "speedy" comments were broken or potentially mis-interpreted, and floppy sizes weren't detected and supported correctly under all circumstances. Thanks, folks!
  • Ralph "pps" for redesigning the Atari++ home page and hosting the whole project. Unfortunately, my employer can no longer host it when I moved.
  • "Phaeron" for documenting many undocumented chipset and CPU features and for answering all my questions. Many of the improvements made in release 1.70 are due to his work. ๐Ÿ‘‘

๐Ÿ“š REFERENCES ๐Ÿ“š

  • DE RE ATARI โ€” by John Eckstrom, Michael A. Eckberg, Gus Makreas, Lane Winner and Elizabeth Hernaton.
  • Das Atari Profibuch โ€” by Julian Reschke and Andreas Wiethoff, Sybex, 1985.
  • 6502 Assembly Language Programming โ€” by Lance A. Leventhal, McGraw-Hill, 1979.
  • Atari Technical Documentation โ€” from The Atari Historical Society at www.atari-history.com
  • Your Atari Computer โ€” by Lon Pool, Martin McNiff & Steven Cook, McGraw-Hill, 1982. German translation "Mein Atari Computer" by te-wi, 1983.

โœ๏ธ AUTHOR โœ๏ธ

Thomas Richter (thor@math.tu-berlin.de)


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

An Atari800.


and that's the whole page bestie, we made it to the end ๐Ÿซถ This gorgeous thing is the atari++ Emulator manual, atari++(6), and that footer energy? Iconic. Periodt. ๐Ÿ’–๐ŸŒธ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from