AROS ​​Vision

Modern and free Amiga-Compatible Experience on Amiga and PC

Amiga Graphics Modes: OCS, ECS, AGA 

The Amiga's display hardware is a set of custom chips. Agnus/Alice handles DMA, the blitter and the Copper, and Denise/Lisa converts bitplanes into pixels, colors and sprites. Each chipset generation extended these chips, so the available modes build on each other. 

Basic concepts (all chipsets) 

Planar graphics. The Amiga doesn't store "one byte per pixel." The image is split into bitplanes: each plane holds one bit per pixel, and the bits from all planes at the same position form the color register index. With n planes you get 2ⁿ colors (5 planes = 32 colors). 

Timing. Everything derives from the color clock: 3.546895 MHz on PAL and 3.579545 MHz on NTSC. The standard horizontal frequency is about 15.6 kHz (TV-compatible), at 50 Hz (PAL) or 60 Hz (NTSC). 

Pixel widths: 

Lowres  Pixel duration 140 ns Typical Width 320 px 
Hires Pixel duration 70 ns Typical width 640 px 
SuperHires (ECS+) pixel duation 35 ns typical width 1280 px 

Vertical resolution:•       

NTSC: 200 lines, 400 with interlace
PAL: 256 lines, 512 with interlace
Interlace alternates even and odd lines on each field, which causes the well-known flicker on 15 kHz monitors. 

Overscan. 

By extending the display window (DIWSTRT/DIWSTOP) and data fetch (DDFSTRT/DDFSTOP), you can fill the whole visible screen. That's roughly 352–368 × 283 lowres on PAL, depending on the monitor.

Copper. 

The coprocessor can rewrite hardware registers synchronized to the video beam. That's what makes these possible: •       different colors per line (copper gradients, "more colors than registers") •       several screens with different resolutions stacked vertically (draggable screens in Intuition) •       tricks like Sliced HAM 

DMA bandwidth. 

Bitplane data shares the chip bus with the CPU, blitter, audio, disk and sprites. The more planes and the higher the resolution, the fewer cycles remain for everything else. This is the real limit behind most mode restrictions. 

OCS – Original Chip Set (A1000, early A500/A2000) 

Chips: Agnus (8361/8367, later Fat Agnus 8370/8371) and Denise (8362). There is 512 KB of addressable chip RAM. 

Palette: 12-bit RGB (4 bits per channel), which gives 4096 possible colors and 32 color registers. 

Lowres (320×256/200) max planes 5 colours 32 
Lowres EHB max planes 6 colours 64 
Lowres HAM6 max planes 6 colours up to 4096 
Hires (640×256/200) planes 4 colours 16 each of the above + interlace same same 

Extra Half-Brite (EHB). 

The 6th plane selects a half-brightness copy of the 32 registers, giving 32 + 32 darker shades. The early A1000 Denise lacks it. 

Hold-And-Modify (HAM6). Of the 6 bits per pixel, 2 are control bits and 4 are data: •       00 takes a color from the first 16 registers. •       01, 10 and 11 keep the previous pixel's color and replace only its blue, red or green component with the 4 data bits. So all 4096 colors can appear at once, but abrupt color changes cause "fringing" (smearing over 2–3 pixels). HAM6 works in lowres only, which makes it ideal for photos and poorly suited to sharp graphics. 

Dual Playfield. Two independent layers with separate scrolling, one transparent over the other: •       lowres: 2 × 3 planes, 7 colors + transparency each •       hires: 2 × 2 planes, 3 colors + transparency each This is typical for parallax games. 

Hardware sprites. There are 8 sprites, each 16 pixels wide (in lowres pixels) and unlimited in height. Each has 3 colors + transparency, and two sprites can be "attached" to form one 15-color sprite. Sprites can be reused further down the screen ("multiplexing"). 

Other notes:•       Hires with 4 planes consumes practically all bitplane DMA slots, so the CPU slows down noticeably in chip RAM. •       Lowres with 6 planes also takes away many CPU cycles. 


ECS – Enhanced Chip Set (A500+, A600, A3000, later A2000) 

Chips:•       Super Agnus: 8372A with 1 MB chip RAM, 8372B/8375 with 2 MB •       Super Denise: 8373 The palette and the 32 color registers stay the same, so the classic modes are identical to OCS. What's new: 

SuperHires (1280 px). 35 ns pixels with at most 2 planes, so 4 colors. In this mode Super Denise outputs only the upper 2 bits per color channel, so the 4 colors come from a reduced palette of 64 colors. 

Programmable scan rates (VARBEAMEN). Agnus's beam counters can be programmed freely. This made new monitor types possible, though they need a multisync or VGA monitor: Mode Resolution (typical) Horizontal freq. Colors Productivity 640×480 (non-interlaced) 31 kHz 4 Euro72 640×400 31 kHz, 70 Hz 4 Super72 ~800×300 (interlace ~800×600) ~24 kHz 4 Euro36 640×200/400 15 kHz, 73 Hz as usual The low color counts come from bandwidth: at 31 kHz, a line has only half the time, so only 2 planes fit into the available DMA slots. 

A2024 mode. Not a chipset mode as such, but supported by OS 2.0. A special monochrome monitor (1008×800/1024 grayscale) assembled one image from several frames. 

Smaller improvements:•       larger maximum display window •       border blanking, so the border can be black regardless of color 0 •       better genlock control •       sprites in more flexible positions

The AGA Chipset in detail 

AGA (“Advanced Graphics Architecture”, called AA by Commodore) is the third and last Amiga chipset generation (1992). It appeared in the A1200, A4000/A4000T and CD32. AGA is not a redesign: it keeps the OCS/ECS architecture and register model, widens the data paths for bitplanes and sprites, and greatly enlarges the palette. That’s why almost all ECS software runs on it, and also why some AGA limits (the 16-bit blitter, the planar model) remain. 

1. The chips

Alice (8374) Predecessor Agnus (8361/8370/8372) Role in AGA DMA controller, Copper, blitter, beam counters, chip RAM addressing (2 MB), 32-bit bus for bitplane and sprite fetches
Lisa (4203) Predecessor Denise (8362/8373) Role in AGA Video output: bitplanes → color index → palette; 256 color registers with 24 bits, sprites, collision detection
Paula (8364) Predecessor unchanged Role in AGA 4-channel 8-bit audio, floppy, serial port, interrupts
CIA (8520) ×2 Predecessor unchanged Role in AGA Timers, keyboard, parallel port, joystick/mouse buttons 

Machine-specific chips around AGA:
A1200: Gayle (IDE, PCMCIA) and Budgie (bus controller)
A4000: Ramsey (fast RAM controller), Gary/Buster (bus, Zorro III)
CD32: Akiko (CD controller and a hardware chunky-to-planar helper)

2. Chip bus and DMA 

All custom chip DMA runs in fixed time slots per scanline, still clocked by the color clock (3.546895 MHz PAL / 3.579545 MHz NTSC). A slot is one memory cycle of about 280 ns. Slots are shared between: 

fixed DMA: memory refresh, disk, audio, sprites
bitplane DMA: the highest priority within the visible area
Copper, blitter and CPU: whatever is left

What AGA changes: the number of slots stays the same, but Alice can fetch 32 or 64 bits per bitplane or sprite slot instead of 16. The theoretical bitplane bandwidth therefore rises from about 7 MB/s (16-bit) to about 28 MB/s (64-bit). That’s what makes 8 planes in hires/superhires and 256 colors at 31 kHz possible at all. 

What stays the same: 

Blitter: still 16 bits wide and no faster than ECS. With 8 bitplanes, every blit has to process 8 planes, which is the main reason AGA is slow for games.
Copper: still writes 16-bit registers, one MOVE per instruction.
CPU access to chip RAM: is not accelerated by the wider fetches. Chip RAM stays slow, which is why an A1200 without fast RAM feels sluggish.

3. Fetch modes (FMODE) 

The new register FMODE ($DFF1FC) controls the fetch width:

Bit 1–0 Name BPL32, BPAGEM Meaning Bitplane fetch width: 00 = 16, 01/10 = 32, 11 = 64 bit
Bit 3–2 Name SPR32, SPAGEM Meaning Sprite width: 16, 32 or 64 pixels
Bit 14 Name BSCAN2 Meaning Bitplane scan doubling (each line output twice)
Bit 15 Name SSCAN2 meaning Sprite scan doubling 

Requirements for wider fetch modes: 

Alignment: bitplane pointers must be aligned to 32 bits (2×) or 64 bits (4×). The same applies to sprite data at the corresponding width.
Width: the fetched line width must be a multiple of 32 or 64 pixels. DDFSTRT/DDFSTOP work with coarser granularity.
Modulos: because fetching overshoots, BPL1MOD/BPL2MOD often have to be adjusted. Wrong modulos show up as a slanted or shredded image.
Benefit: besides enabling high-depth modes, wider fetches free up DMA slots for the CPU and blitter, even in “normal” modes.

4. Bitplanes and display control 

Bitplane pointers: BPL1PT to BPL8PT ($DFF0E0 to $DFF0FE). Planes 7 and 8 are new. 

BPLCON0 ($DFF100): 
The number of planes is set by the 3 BPU bits plus the new BPU3 (bit 4) for 8 planes.
HIRES (bit 15), SHRES (bit 6), HAM (bit 11), DPF (dual playfield, bit 10), LACE (bit 2)
ECSENA (bit 0) enables the extended functions of BPLCON3.

BPLCON1 (scrolling): extra bits allow fine scrolling in steps of 35 ns (one superhires pixel) and a larger scroll range. Smooth scrolling therefore also works in hires and superhires. 

BPLCON2 (priorities): 
playfield and sprite priorities
KILLEHB (bit 9): switches off Extra Half-Brite, so 6 planes give 64 normal colors
RDRAM (bit 8): reads color registers back
genlock-related bits

BPLCON3 ($DFF106), the key AGA register:
Bits 15–13 Name BANK2–0 Meaning Selects which block of 32 among the 256 color registers COLOR00–COLOR31 currently addresses
Bits 12–10 Name PF2OF2–0 Meaning Color offset for playfield 2 in dual-playfield mode
Bit 9 Name LOCT Meaning 0 = write the upper 4 bits per channel, 1 = the lower 4 bits
Bits 7–6 Name SPRES1–0 Meaning Sprite resolution (lowres/hires/superhires)
Bit 5 Name BRDRBLNK Meaning Blank the border (black instead of color 0)4BRDNTRANBorder not transparent for genlock
Bit 1 Name BRDSPRT Meaning Sprites visible in the border0EXTBLKENExternal blank signal 

BPLCON4 ($DFF10C): 
BPLAM7–0 (bits 15–8): an XOR mask applied to every bitplane color index. A single register write switches a screen to a completely different region of the palette, a cheap trick for color cycling and fades.
ESPRM7–4 / OSPRM7–4: select the color bank (a 16-color block) for even and odd sprites separately.

5. Palette and color registers 

There are 256 registers with 24-bit RGB (8 bits per channel). For OCS compatibility, COLOR00–COLOR31 remain 12-bit registers. A full 24-bit color is written in two steps:

BPLCON3 = BANK n, LOCT=0 ; select bank COLORxx = $0RGB ; upper nibbles of R, G, B BPLCON3 = BANK n, LOCT=1 COLORxx = $0rgb ; lower nibbles of R, G, B Consequences: When only the upper nibbles are written (as ECS software does), Lisa duplicates them into the lower nibbles ($F → $FF). So old programs get correct colors.

 A complete 256-color palette needs over 500 register writes. Doing this via the Copper is possible, but takes Copper time and must be planned for (e.g. during vertical blanking).

Under the OS: use LoadRGB32()/SetRGB32() from graphics.library. They take 32 bits per channel and handle banks and LOCT themselves.

6. Color modes

Normal Planes 1–8 Colours 2–256 Note in all resolutions (8 planes in hires/superhires need 2×/4× fetch)
EHB Planes 6 Colours 64 Note still available, can be switched off with KILLEHB
HAM6 Planes 6 Colours 4096 Note OCS-compatible
HAM8 Planes 8 Colozrs up to 262,144 Note 2 control + 6 data bits; 64 base colors (24-bit); modifications change the upper 6 bits of one channel
Dual Playfield Planes 2 × up to 4 Colours 2 × 15 + transparency Notes PF2OF sets the palette offset of playfield 2 

HAM8 in practice: fringing is much less noticeable than with HAM6, and HAM8 also works in hires and superhires. It suits photos and video stills well, and is poorly suited to moving graphics because CPU encoding is expensive. 

7. Sprites 

The count stays at 8 hardware sprites, but each is much more flexible: 

Width: 16, 32 or 64 pixels (FMODE bits 3–2). At greater widths the sprite data must be aligned accordingly.
Resolution: independent of the screen, via SPRES (sprite pixels at 140, 70 or 35 ns).
Colors: 3 + transparency per sprite, or 15 + transparency for an attached pair. The color bank is selectable via BPLCON4, so sprites no longer have to share colors 16–31 with the bitplanes.
Border: with BRDSPRT, sprites can also be shown outside the display window.
Scan doubling: SSCAN2 keeps sprite proportions correct in DblPAL/DblNTSC.
Collision: CLXCON covers sprites and planes 1–6, and the new CLXCON2 ($DFF10E) adds planes 7–8.

8. Beam timing and monitor modes 

Since ECS, the beam counters are programmable (BEAMCON0, HTOTAL, HSSTRT/HSSTOP, HBSTRT/HBSTOP, VTOTAL, VSSTRT/VSSTOP, VBSTRT/VBSTOP, HCENTER). AGA uses this for: 

15 kHz: PAL/NTSC (TV, 1084)
31 kHz: DblPAL, DblNTSC, Multiscan/Productivity, Euro72 (VGA/multisync monitor)
~24 kHz: Super72

The scan-doubling bits (BSCAN2/SSCAN2) let a 31 kHz mode show the content of a PAL/NTSC screen flicker-free, which is how DblPAL works. Under the OS, the monitor drivers in DEVS:Monitors set this timing; you select the mode via ModeID and never program the registers yourself. 

9. Compatibility 

At reset, Alice and Lisa behave like ECS: FMODE = 0, BPLCON3/4 neutral, the first 32 registers active.
Problem cases are programs that never initialize the new registers and inherit leftover values from the OS or a previous program: 

a non-zero BPLCON4 produces “shifted” colors
FMODE ≠ 0 shreds the display
wrong sprite widths

Remedies: the Early Startup menu (both mouse buttons at boot) offers a choice of chipset emulation (Original/ECS/AGA). Degrader tools exist too. Programs of your own should always set FMODE, BPLCON3 and BPLCON4 explicitly when they take over the hardware.

10. Detecting AGA 

Via the OS (recommended): check GfxBase->ChipRevBits0 for GFXF_AA_ALICE and GFXF_AA_LISA.
Directly in hardware: DENISEID/LISAID ($DFF07C). Lisa returns $F8 in the low byte, ECS Denise $FC, and OCS Denise has no ID register (undefined values). Read it several times and mask it.

11. The limits of AGA 

Planar only. There is no chunky mode with one byte per pixel. 3D games and video need C2P conversion in software, which costs a lot of CPU time on the A1200 (68EC020). Only the CD32’s Akiko helps in hardware.
Blitter unchanged. It is 16-bit and as slow as on ECS, so with 8 planes it is often slower than a 68030/040 copying with the CPU.
Chip RAM is only 2 MB and slow for the CPU. Without fast RAM, the A1200 is severely limited.
No higher resolution with many colors. 256 colors at 31 kHz are possible, but use almost all the bandwidth. True high resolutions with truecolor require RTG.
The successor never shipped. The AAA chipset (chunky modes, 32-bit blitter) and later plans such as Hombre were cancelled with Commodore’s bankruptcy in 1994.

12. For your AROS m68k projects 
#
AROS: the amigavideo.hidd driver drives AGA. You use the same OS APIs as on AmigaOS: ModeIDs, LoadRGB32(), and AllocBitMap() with a friend bitmap. AROS handles FMODE, banks and Copper lists.
Video playback on AGA (e.g. ffplay): typically an 8-bit screen with an optimized palette plus fast C2P, or HAM8 for stills. RTG is far better if available.
Direct hardware access only after LoadView(NULL)/OwnBlitter() or a clean takeover, and restore all AGA registers properly on exit.

How the original Amiga graphics modes work on AROS m68k 

On AmigaOS, graphics.library is the chipset driver: it builds Copper lists and drives Agnus/Denise directly. On AROS m68k, graphics.library is hardware-independent, and the custom chipset is driven by a separate display driver, amigavideo.hidd. Everything about the original modes (which modes exist, how screens appear, how colors get into the hardware) runs through that driver. 

One caveat up front: AROS’s m68k developer documentation is partly older than the current code. Where something has changed recently, or where a limitation may already be fixed, I say so. 

1. Architecture

Application (OpenScreen, ModeID, LoadRGB32, RectFill …) 
│ 
graphics.library (AROS, hardware-independent) 
│ HIDD methods: NewBitMap, Show, ShowViewPorts, PutImage, FillRect … 
▼ 
amigavideo.hidd 
├── Gfx class → mode database, sync/pixel formats 
├── Bitmap class → planar bitmaps in chip RAM 
└── Compositor class → builds the Copper list for the visible screens 
│ 
Alice/Agnus, Lisa/Denise (custom chips)

Bitmaps: the AmigaGFX bitmap class is a subclass of AROS’s generic planar bitmap class. Chipset bitmaps are therefore genuinely planar in chip RAM, just as on AmigaOS.
Display: the compositor class manages the Copper list that displays the Amiga screen(s). When the stack of visible screens changes (BitMapStackChanged), the compositor recomputes the Copper data for each viewport.

2. Chipset detection: OCS/ECS vs AGA 

The driver decides at startup which features to use. AGA modes and AGA Copper lists are only used when AGA is present and “enabled”, i.e. GfxBase->ChipRevBits0 == SETCHIPREV_AA. 

Consequences: 
If the chip revision is downgraded (Early Startup, or tools that set ChipRevBits), the driver behaves like ECS: 32 color registers, 12-bit colors, no 8-bit depths.
With AGA enabled, 24-bit AGA colors are supported. Palette writes go to both the upper and the lower nibbles (via LOCT). The driver keeps separate Copper palette entries for this, and separate ones again for interlace.

3. How chipset modes get into the mode database 

This is the trickiest part of the design, because AROS’s HIDD model thinks in pixel formats, while the Amiga thinks in depths: 

In the HIDD world, one pixel format corresponds to one depth. Supporting AGA fully means providing 8 pixel formats, and 4 or 5 for OCS/ECS depending on horizontal resolution.
That in turn means one AGA resolution needs 8 different ModeIDs.
There was a related problem: AllocBitMap() passes width, height and pixel format to the HIDD, but not the depth, which the chipset modes really need.

The documentation describes these as open problems at the time; they were solved in the meantime, since depth-dependent chipset screens work. What’s useful to know is the result: the mode database lists chipset modes per depth, which looks different from AmigaOS in ScreenMode prefs and when enumerating modes. 

Which base modes exist: 
Default modes: 640×256 PAL (×512 interlaced) and 640×200 NTSC (×400 interlaced).
PAL and NTSC: both are added to the mode database if the chipset can switch between them, i.e. from ECS Agnus onwards.
Lowres, hires, superhires (ECS/AGA) and interlace are covered by the driver; the separate interlace Copper lists mentioned above show the latter is handled.
31 kHz/special monitors (DblPAL, DblNTSC, Multiscan, Euro72, Super72, A2024): older AROS documentation lists these monitor files as missing from DEVS:Monitors. I can’t confirm the current state with certainty. Check Prefs/ScreenMode on your build to see which of these modes it actually offers.

4. Special modes: HAM and EHB 

The modes exist in the database. Developer notes say the DIPF_IS_WB flag must not be set in special chipset modes like HAM, which implies HAM modes have their own entries with their own properties.
Pixel content is the program’s job. As on AmigaOS, graphics.library doesn’t encode HAM. Writing truecolor data with WritePixelArray() onto a HAM screen does not produce a correct HAM image. You must compute the HAM bitplanes yourself (as image converters do).
EHB: the 6th plane is interpreted as on AmigaOS. The palette only needs the 32 base colors.
HAM8 naturally requires AGA to be enabled (see section 2).

5. Screens, Copper, dragging 

Because the compositor builds the Copper list, the driver controls how several screens appear at once: Known limitation (2019 TODO list): after screen switching, the palette of the last opened screen is always used, and screen dragging only works with a single visible screen. Both issues are related, since the visible screens and their pens are set via the Copper. The Copper code needed refactoring so that each visible screen injects its own display parameters and colors.

Since then: the AROS ABIv0 release of November 2020 lists major extensions to amigavideo.hidd, work on screen compositing, and support for user Copper lists. The July 2025 – July 2026 highlights also mention a fixed AGA palette crash.

 Practical takeaway: test the dragging and multi-screen behavior on your current build rather than relying on either the old TODO list or AmigaOS behavior.
User Copper lists (UCopList, e.g. for color gradients) are supported, so classic Copper effects via the OS are possible.

6. Mode selection: 

RTG takes priority When a graphics card is present, AROS prefers it: BestModeID(): on m68k-amiga it is overridden to look for RTG modes first, and to check chipset modes only if the RTG scan finds nothing.
Mode promotion: AmigaOS-style mode promotion (redirecting standard chipset modes to RTG) remained an open design question for AROS.
Consequence: if your program specifically wants a chipset mode (e.g. HAM8 or a PAL mode for a TV), request it explicitly with BIDTAG_MonitorID (PAL_MONITOR_ID, NTSC_MONITOR_ID, ...) or with a fixed chipset ModeID from NextDisplayInfo(), and don’t rely on BestModeID() alone. 7. Mouse pointer and sprites The pointer is shown with a hardware sprite. The 2019 TODO list notes that sprite loading did not yet remap colors properly or set the sprite pens, so pointer colors could be wrong. Here too, check your current build. 8. Direct hardware access (games and demos) On AROS m68k, the custom chips are just as accessible as on AmigaOS, because the code runs natively on the hardware: Clean takeover: LoadView(NULL), WaitTOF() ×2, OwnBlitter()/WaitBlit(), Forbid() or a system takeover. Programs that do this properly generally work.
Restoring: on exit, LoadView(GfxBase->ActiView) and RethinkDisplay(). The OS Copper list is rebuilt by amigavideo.hidd, not by AmigaOS code.
Risky: programs that rely on internal AmigaOS graphics.library structures (e.g. reading or patching GfxBase->copinit, or the OS’s internal Copper lists), because those structures are created differently on AROS or don’t exist.
AGA registers: set FMODE, BPLCON3 and BPLCON4 explicitly, since AROS leaves them in whatever state its own Copper list needs.

9. Practical tips for your projects 

Check the available chipset modes at runtime with NextDisplayInfo() + GetDisplayInfoData() (DTAG_DIMS, DTAG_DISP for PropertyFlags like DIPF_IS_HAM, DIPF_IS_EXTRAHALFBRITE, DIPF_IS_AA).
Check for AGA via GfxBase->ChipRevBits0 before offering 256-color or HAM8 modes.
Request chipset modes explicitly with the monitor ID when a graphics card might be present.
Load palettes with LoadRGB32(). The driver takes care of banks and LOCT.
Allocate bitmaps for chipset screens with a friend bitmap. That way they end up planar in chip RAM in the right format.
Test in FS-UAE with an A1200/AGA configuration and no RTG card, so that the chipset path is really used.

AROS m68k RTG in detail (CybergraphX)

On AROS m68k, RTG is not an add-on as it is on AmigaOS 3.x. The graphics system is driver-based from the ground up: the native chipset and a graphics card are both just display drivers (HIDDs) under the same graphics.library. Card support itself reuses the existing Picasso96 drivers through a wrapper. 

1. Layer model

Applications 
│ graphics.library / intuition / cybergraphics.library 
▼ 
graphics.library (AROS) ── display database, ModeIDs, ViewPorts 
│ OOP method calls 
▼ 
Graphics HIDDs (driver classes) 
├── amigavideo.hidd → OCS/ECS/AGA (Copper, planar bitmaps) 
└── p96gfx.hidd → Picasso96 wrapper 
                                                   │ BoardInfo interface 
                                                  ▼ 
                       card / .chip drivers (P96 format) 
                                                  ▼ 
                          graphics card hardware 

2. The HIDD driver model 

Driver structure. A graphics driver is a class derived from CLID_Hidd_Gfx, and only a few methods have to be implemented. Through CreateObject() it produces graphics contexts (CLID_Hidd_GC) and bitmaps (CLID_Hidd_BitMap), plus optional objects like I2C or Gallium 3D drivers. 

Modes. The driver reports its modes (pixel formats and syncs), and graphics.library uses them to populate its display database and to choose which bitmap class to use for a given mode. Each driver is registered with AddDisplayDriverA(), which assigns it a base ModeID (e.g. 0x00140000); the lower word of the ModeID then selects the mode within that driver. 

Consequence: RTG ModeIDs on AROS are not the same values as on a P96 system and depend on the order in which drivers are loaded. Never hard-code them. 

Rendering. Bitmap classes implement methods such as PutPattern, GetImage, GetPixel, DrawLine, FillRect and so on. A driver accelerates what it can; anything else falls back to the generic implementation in the base class. 

Friend bitmaps. A new bitmap inherits the class, layout and pixel format of its friend bitmap. If you specify a different pixel format explicitly, it gets a different class, and the “friendship” is effectively broken. In practice, bitmaps with a friend end up in the card’s format and video memory, while bitmaps without one end up in a generic memory class. 

3. The two drivers on m68k 

amigavideo.hidd (native chipset)

Drives OCS/ECS/AGA with planar bitmaps.
A compositor class manages the Copper list that displays the Amiga screen(s).
Known weakness: after screen switching, the palette of the last opened screen is always used, and the Copper code still needs refactoring before AmigaOS-style screen dragging works.

p96gfx.hidd (graphics cards) 

A HIDD wrapper that loads Picasso96 .card and .chip driver files. Hardware support therefore depends on the existing P96 driver ecosystem.
Internally it emulates P96’s BoardInfo interface. Third-party drivers use its published structure offsets: the P96Multicast project, for instance, wrote its BoardInfo layout from the offsets of AROS’s p96gfx.hidd and WinUAE.
With RTG active, even the boot menu and boot image use the RTG mode automatically.
Historically, UAE’s emulated graphics card came first (as uaegfx.hidd), followed by support for real boards through AmigaOS P96 .card/.chip files.

4. Installation and configuration 

Where the files go: 
P96 card and chip files go in LIBS:Picasso96/, as on AmigaOS. Some come in pairs (.card + .chip), and their order doesn’t matter.
The monitor entry goes in DEVS:Monitors.

Key difference from P96 on AmigaOS: P96 on AmigaOS: you create a monitor icon in DEVS:Monitors and set its BOARDTYPE tooltype to the card.
AROS: you copy DEVS:Monitors/P96 to DEVS:Monitors/<CardName>. The monitor driver opens the card whose name matches its own filename.

 Example: for Z3660.card, the monitor file is DEVS:Monitors/Z3660.

Recent change: among AROS’s highlights for July 2025 – July 2026 is that Picasso96 card drivers now load from DEVS:Monitors. Older guides that describe boot-time resident tricks (e.g. raising an RTG driver’s resident priority above uaegfx.hidd) are therefore outdated. Emulators (FS-UAE/WinUAE): Set the RTG card memory (up to 32 MB in FS-UAE). That enables the emulated Picasso96-compatible card.

 A practical example: P96Multicast was tested under AROS m68k’s P96 layer in FS-UAE.

5. Chipset and RTG on one monitor (passthrough) 

Many real Amiga graphics cards have a passthrough: one monitor shows either the card’s output or the chipset’s looped-through signal. AROS has to emulate this switching across two separate drivers. The intended behavior: if the topmost screen is an RTG screen, RTG output is enabled; if it is a chipset screen, RTG is disabled and the chipset passthrough is turned on.
So when the chipset driver shows a screen, the RTG driver must be told to hide (Show(NULL)), and vice versa. That’s coordination between two separate HIDDs, which is a source of edge-case bugs.
BestModeID(): on m68k-amiga it is overridden to look for RTG modes first and to check chipset modes only if the RTG scan finds nothing. Programs that call BestModeID() without restrictions therefore usually get an RTG mode when a card is present. Request the monitor ID explicitly (e.g. PAL_MONITOR_ID) if you need a chipset mode.
Mode promotion (redirecting standard chipset ModeIDs to RTG, as P96 does) was still an open design question in AROS’s developer documentation. Don’t rely on it.

6. Rendering path and acceleration 

A RectFill() on an RTG screen takes this route: 
graphics.library (with layers/clipping)
→ the bitmap’s HIDD method FillRect
→ p96gfx.hidd translates to the card’s P96 hook (FillRect, BlitRect, ...)
→ the card driver uses the graphics chip’s blitter, or the CPU if the hook is missing

Things to know: Missing hooks: if a driver doesn’t implement a hook, a default implementation in P96’s shared code takes over, so a missing hook still renders, just in software. Per the AROS m68k TODO list, some accelerated blit methods in p96gfx.hidd are not implemented yet, which can mean sub-optimal performance on some hardware.

Framebuffer-only cards: cards without a blitter are drawn entirely by the CPU, which is the right approach for a framebuffer in fast RAM.

Sprites: sprite loading in p96gfx.hidd doesn’t remap colors properly yet the way the amigavideo driver does. Watch for wrong mouse pointer colors on RTG.

 Correctness: the P96 conformance suite p96cts runs on AROS too and compares pixel by pixel. Known divergences on RTG modes (tested with Z3660 and ZZ9000) are tracked in AROS issue #936, and BitMapScale divergences in #950.

7. Programming interfaces for applications

API graphics.library/Intuition Status fully RTG-capable; AllocBitMap() with a friend bitmap, BMF_SPECIALFMT
API cybergraphics.library Status native, the main truecolor API (LockBitMapTags, WritePixelArray, alpha functions, ...)
API Picasso96API.library Status not present; the p96cts suite falls back to cybergraphics.library and graphics.library on AROS 

Real projects follow the same pattern: DOpus5, for example, compiles out its P96 calls on AROS and routes RTG through CyberGraphX. 

8. Practical recommendations for your projects

Choose the mode with tags: BestCModeIDTagList() with depth/size for RTG, and an explicit PAL_MONITOR_ID/DBLPAL_MONITOR_ID for AGA. Offer the ASL requester as an option.
Video output: with RTG, WritePixelArray() in large blocks or a locked framebuffer (with a NULL check). With AGA, a C2P path into planar bitmaps.
Allocate all buffers with the screen’s bitmap as the friend.
Test both paths: in FS-UAE with the emulated card and with AGA-only. If you have it, test on real hardware with a P96 board too, since driver gaps only show up there.
Keep p96cts at hand to tell whether a rendering error comes from your code, from AROS’s graphics layer, or from the card driver.