amiga-bootcamp/08_graphics/gfx_base.md

237 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[← Home](../README.md) · [Graphics](README.md)
# GfxBase — Graphics Library Global State
## Overview
`graphics.library` is the core drawing library in AmigaOS. It manages all display output, drawing primitives, font rendering, and custom chip programming. `GfxBase` — the library base — contains the system's display state, chip revision info, system copper lists, and the display mode database.
```mermaid
flowchart TD
subgraph "GfxBase — Global Graphics State"
AV["ActiView<br/>(current display)"]
COP["copinit<br/>(system copper list)"]
CHIP["ChipRevBits0<br/>(OCS/ECS/AGA detection)"]
FONTS["TextFonts<br/>(system font list)"]
MODES["ModesList<br/>(display mode database)"]
VBF["VBlankFrequency<br/>(50=PAL, 60=NTSC)"]
end
APP["Application"] -->|"OpenLibrary"| GFX["graphics.library"]
GFX --> AV
GFX --> COP
GFX --> CHIP
AV -->|"MakeVPort / MrgCop /<br/>LoadView"| HW["Custom Chips<br/>(Agnus/Denise)"]
style GFX fill:#e8f4fd,stroke:#2196f3,color:#333
style HW fill:#c8e6c9,stroke:#2e7d32,color:#333
```
---
## struct GfxBase (Key Fields)
```c
/* graphics/gfxbase.h — NDK39 */
struct GfxBase {
struct Library LibNode;
struct View *ActiView; /* currently active View */
struct copinit *copinit; /* system copper list initialization */
LONG *cia; /* CIA base (deprecated) */
LONG *blitter; /* blitter base (deprecated) */
UWORD *LOFlist; /* long-frame copper list pointer */
UWORD *SHFlist; /* short-frame copper list (interlace) */
struct bltnode *blthd; /* blitter queue head */
struct bltnode *blttl; /* blitter queue tail */
struct bltnode *bsblthd;
struct bltnode *bsblttl;
struct Interrupt vbsrv; /* vertical blank server chain */
struct Interrupt timsrv; /* timer server chain */
struct Interrupt bltsrv; /* blitter-done server chain */
struct List TextFonts; /* system font list */
struct TextFont *DefaultFont; /* default system font (topaz.8) */
UWORD Modes; /* current display mode bits */
BYTE VBlankFrequency; /* 50 (PAL) or 60 (NTSC) */
BYTE DisplayFlags; /* PAL/NTSC/GENLOCK flags */
UWORD NormalDisplayColumns; /* default display width */
UWORD NormalDisplayRows; /* default display height */
UWORD MaxDisplayColumn;
UWORD MaxDisplayRow;
UWORD ChipRevBits0; /* chip revision flags — see below */
/* ... many more fields ... */
struct MonitorSpec *monitor_id;
struct List MonitorList; /* installed monitors */
struct List ModesList; /* display mode database */
UBYTE MemType; /* memory type flags */
/* OS 3.x additions */
APTR ChunkyToPlanarPtr; /* c2p conversion routine pointer */
};
```
---
## Chip Revision Detection
The `ChipRevBits0` field identifies which chipset generation is present — essential for FPGA cores that need to report their emulated chipset level:
```c
/* graphics/gfxbase.h */
#define GFXB_BIG_BLITS 0 /* big blitter (ECS Agnus — 1MB chip) */
#define GFXB_HR_AGNUS 0 /* hi-res Agnus (same bit as above) */
#define GFXB_HR_DENISE 1 /* ECS Denise (SuperHires, scan-doubling) */
#define GFXB_AA_ALICE 2 /* AGA Alice (A1200/A4000) */
#define GFXB_AA_LISA 3 /* AGA Lisa (A1200/A4000) */
#define GFXB_AA_MLISA 4 /* AGA modified Lisa */
#define GFXF_BIG_BLITS (1<<0)
#define GFXF_HR_AGNUS (1<<0)
#define GFXF_HR_DENISE (1<<1)
#define GFXF_AA_ALICE (1<<2)
#define GFXF_AA_LISA (1<<3)
#define GFXF_AA_MLISA (1<<4)
```
### Detecting the Chipset
```c
struct GfxBase *GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 0);
if (GfxBase->ChipRevBits0 & GFXF_AA_ALICE)
{
/* AGA chipset (A1200/A4000) */
/* 8-bit planar, 256 colors, 24-bit palette */
}
else if (GfxBase->ChipRevBits0 & GFXF_HR_DENISE)
{
/* ECS chipset (A3000/A600) */
/* SuperHires, productivity modes, scan-doubler */
}
else if (GfxBase->ChipRevBits0 & GFXF_HR_AGNUS)
{
/* ECS Agnus with OCS Denise (A500+/A2000 upgraded) */
/* 1 MB Chip RAM support, but no ECS display features */
}
else
{
/* OCS chipset (original A500/A1000/A2000) */
/* 512 KB Chip RAM, 4096 color palette */
}
```
| Bits Set | Chipset | Systems |
|---|---|---|
| None | OCS | A500, A1000, A2000 |
| `HR_AGNUS` | ECS Agnus only | A500+ (Fat Agnus upgrade) |
| `HR_AGNUS + HR_DENISE` | Full ECS | A600, A3000 |
| `AA_ALICE + AA_LISA` | AGA | A1200, A4000, CD32 |
---
## PAL vs NTSC Detection
```c
if (GfxBase->VBlankFrequency == 50)
{
/* PAL: 50 Hz, 312 lines/field, 625 total (interlaced) */
/* Standard resolution: 320×256 */
}
else /* 60 */
{
/* NTSC: 60 Hz, 262 lines/field, 525 total (interlaced) */
/* Standard resolution: 320×200 */
}
/* DisplayFlags also has the info: */
if (GfxBase->DisplayFlags & PAL) /* PAL system */
if (GfxBase->DisplayFlags & NTSC) /* NTSC system */
```
---
## The Display Pipeline
```mermaid
flowchart TD
subgraph "Application"
VP["ViewPort<br/>(one per screen)"]
end
subgraph "GfxBase Pipeline"
MV["MakeVPort(view, vp)<br/>→ build copper instructions<br/>for this viewport"]
MC["MrgCop(view)<br/>→ merge all viewport copper<br/>into single list"]
LV["LoadView(view)<br/>→ install merged copper list<br/>into hardware"]
end
subgraph "Hardware"
COP["Copper DMA<br/>executes copper list"]
CHIPS["Custom Chips<br/>display image"]
end
VP --> MV --> MC --> LV --> COP --> CHIPS
style MV fill:#fff9c4,stroke:#f9a825,color:#333
style MC fill:#fff9c4,stroke:#f9a825,color:#333
style LV fill:#fff9c4,stroke:#f9a825,color:#333
```
### Key Display Functions
| Function | Purpose |
|---|---|
| `MakeVPort(view, vp)` | Generate copper instructions for one ViewPort |
| `MrgCop(view)` | Merge all ViewPort copper lists into unified system list |
| `LoadView(view)` | Install the merged copper list into the hardware (LOF/SHF) |
| `WaitTOF()` | Wait for top of frame (vertical blank) — used to sync display updates |
| `WaitBOVP(vp)` | Wait for the beam to pass a specific ViewPort |
---
## Blitter Queue
GfxBase maintains a queue of pending Blitter operations (`blthd`/`blttl`). When an application calls `BltBitMap`, the operation may be queued and executed asynchronously by the Blitter interrupt:
```c
/* Start a blit — may be queued: */
BltBitMap(srcBM, sx, sy, dstBM, dx, dy, w, h, 0xC0, 0xFF, NULL);
/* Wait for ALL pending blits to complete: */
WaitBlit();
/* Or use OwnBlitter/DisownBlitter for exclusive access: */
OwnBlitter(); /* blocks until blitter is free, then locks it */
/* ... direct blitter register access ... */
DisownBlitter(); /* release for other tasks */
```
---
## System Fonts
```c
/* Get the default system font: */
struct TextFont *sysFont = GfxBase->DefaultFont;
Printf("System font: %s, size %d\n",
sysFont->tf_Message.mn_Node.ln_Name,
sysFont->tf_YSize);
/* Enumerate all loaded fonts: */
struct Node *node;
for (node = GfxBase->TextFonts.lh_Head;
node->ln_Succ;
node = node->ln_Succ)
{
Printf("Font: %s\n", node->ln_Name);
}
```
---
## References
- NDK39: `graphics/gfxbase.h`
- ADCD 2.1: graphics.library autodocs
- See also: [views.md](views.md) — View/ViewPort construction
- See also: [copper.md](copper/copper.md) — Copper coprocessor
- See also: [display_modes.md](display_modes.md) — display mode database