DOS_Video/vgaCommon.h
2026-04-13 19:40:45 -05:00

198 lines
6.9 KiB
C

// vgaCommon.h -- Shared VGA register programming for DOS/DJGPP
//
// Provides low-level access to the standard VGA register sets that
// are common across all VGA-compatible video cards. Every chipset
// driver needs these for basic mode setup before enabling its
// chip-specific acceleration extensions.
//
// The five standard VGA register groups:
// - Miscellaneous Output (0x3C2 write, 0x3CC read)
// - Sequencer (0x3C4/0x3C5)
// - CRTC (0x3D4/0x3D5 for color, 0x3B4/0x3B5 for mono)
// - Graphics Controller (0x3CE/0x3CF)
// - Attribute Controller (0x3C0/0x3C1, toggle via 0x3DA read)
//
// All functions use DJGPP's inportb/outportb for port I/O.
#ifndef VGA_COMMON_H
#define VGA_COMMON_H
#include <stdint.h>
#include <stdbool.h>
// ============================================================
// VGA I/O port addresses
// ============================================================
// Miscellaneous output register
#define VGA_MISC_OUT_W 0x3C2 // write
#define VGA_MISC_OUT_R 0x3CC // read
// Input status registers
#define VGA_INPUT_STATUS_0 0x3C2
#define VGA_INPUT_STATUS_1 0x3DA // color mode
#define VGA_INPUT_STATUS_1M 0x3BA // mono mode
// Sequencer
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
// CRTC (color mode addresses -- we always use color)
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
// Graphics Controller
#define VGA_GFX_INDEX 0x3CE
#define VGA_GFX_DATA 0x3CF
// Attribute Controller (index and data share 0x3C0)
#define VGA_ATTR_INDEX 0x3C0
#define VGA_ATTR_DATA_W 0x3C0
#define VGA_ATTR_DATA_R 0x3C1
// DAC (palette)
#define VGA_DAC_READ_ADDR 0x3C7
#define VGA_DAC_WRITE_ADDR 0x3C8
#define VGA_DAC_DATA 0x3C9
#define VGA_DAC_STATE 0x3C7
// Feature control
#define VGA_FEATURE_W 0x3DA // write (color mode)
#define VGA_FEATURE_R 0x3CA // read
// ============================================================
// Sequencer register indices
// ============================================================
#define VGA_SEQ_RESET 0x00
#define VGA_SEQ_CLOCK_MODE 0x01
#define VGA_SEQ_PLANE_MASK 0x02
#define VGA_SEQ_CHAR_MAP 0x03
#define VGA_SEQ_MEM_MODE 0x04
// Sequencer clock mode bits
#define VGA_SEQ_SCREEN_OFF 0x20 // bit 5: blank the screen
// ============================================================
// CRTC register indices
// ============================================================
#define VGA_CRTC_H_TOTAL 0x00
#define VGA_CRTC_H_DISP_END 0x01
#define VGA_CRTC_H_BLANK_START 0x02
#define VGA_CRTC_H_BLANK_END 0x03
#define VGA_CRTC_H_SYNC_START 0x04
#define VGA_CRTC_H_SYNC_END 0x05
#define VGA_CRTC_V_TOTAL 0x06
#define VGA_CRTC_OVERFLOW 0x07
#define VGA_CRTC_PRESET_ROW 0x08
#define VGA_CRTC_MAX_SCAN 0x09
#define VGA_CRTC_CURSOR_START 0x0A
#define VGA_CRTC_CURSOR_END 0x0B
#define VGA_CRTC_START_ADDR_HI 0x0C
#define VGA_CRTC_START_ADDR_LO 0x0D
#define VGA_CRTC_CURSOR_HI 0x0E
#define VGA_CRTC_CURSOR_LO 0x0F
#define VGA_CRTC_V_SYNC_START 0x10
#define VGA_CRTC_V_SYNC_END 0x11
#define VGA_CRTC_V_DISP_END 0x12
#define VGA_CRTC_OFFSET 0x13
#define VGA_CRTC_UNDERLINE 0x14
#define VGA_CRTC_V_BLANK_START 0x15
#define VGA_CRTC_V_BLANK_END 0x16
#define VGA_CRTC_MODE_CTRL 0x17
#define VGA_CRTC_LINE_COMPARE 0x18
// ============================================================
// Graphics controller register indices
// ============================================================
#define VGA_GFX_SET_RESET 0x00
#define VGA_GFX_ENABLE_SET_RESET 0x01
#define VGA_GFX_COLOR_COMPARE 0x02
#define VGA_GFX_DATA_ROTATE 0x03
#define VGA_GFX_READ_MAP_SEL 0x04
#define VGA_GFX_MODE 0x05
#define VGA_GFX_MISC 0x06
#define VGA_GFX_COLOR_DONT_CARE 0x07
#define VGA_GFX_BIT_MASK 0x08
// ============================================================
// VESA mode result (returned by vesaFindAndSetMode)
// ============================================================
typedef struct {
int32_t width;
int32_t height;
int32_t bpp;
int32_t pitch;
uint32_t lfbPhysAddr; // physical address of LFB from VBE
} VesaModeResultT;
// ============================================================
// DPMI LFB mapping result (returned by dpmiMapFramebuffer)
// ============================================================
typedef struct {
uint8_t *ptr; // near pointer to mapped region
uint32_t linearAddr; // linear address (for unmapping)
uint32_t size; // mapped size in bytes
} DpmiMappingT;
// ============================================================
// Prototypes
// ============================================================
// Find the best VESA VBE mode matching the requested resolution
// and bpp, set it with LFB enabled, and return the mode details.
// Returns true on success. This replaces ~150 lines of duplicated
// code in every driver.
bool vesaFindAndSetMode(int32_t reqW, int32_t reqH, int32_t reqBpp, VesaModeResultT *result);
// Map a physical address region into the DJGPP near pointer space
// via DPMI. Handles physical address mapping, page locking, and
// near pointer enable. Returns true on success.
bool dpmiMapFramebuffer(uint32_t physAddr, uint32_t size, DpmiMappingT *mapping);
// Unmap a previously mapped framebuffer region and disable near
// pointers. Safe to call with a zeroed mapping struct.
void dpmiUnmapFramebuffer(DpmiMappingT *mapping);
// Size a PCI BAR by writing all 1s and reading back. Returns the
// decoded size in bytes. Saves and restores the original BAR value.
uint32_t pciSizeBar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t barReg);
// Read/write individual VGA register sets
uint8_t vgaAttrRead(uint8_t index);
void vgaAttrReset(void);
void vgaAttrWrite(uint8_t index, uint8_t val);
uint8_t vgaCrtcRead(uint8_t index);
void vgaCrtcWrite(uint8_t index, uint8_t val);
uint8_t vgaGfxRead(uint8_t index);
void vgaGfxWrite(uint8_t index, uint8_t val);
uint8_t vgaMiscRead(void);
void vgaMiscWrite(uint8_t val);
uint8_t vgaSeqRead(uint8_t index);
void vgaSeqWrite(uint8_t index, uint8_t val);
// CRTC register protection: some CRTC registers are write-protected
// by bit 7 of the V_SYNC_END register. These functions unlock/lock.
void vgaCrtcLock(void);
void vgaCrtcUnlock(void);
// Palette (DAC) operations
void vgaDacReadColor(uint8_t index, uint8_t *r, uint8_t *g, uint8_t *b);
void vgaDacWriteColor(uint8_t index, uint8_t r, uint8_t g, uint8_t b);
// Restore VGA text mode (mode 3). Uses INT 10h for reliability
// across all chipsets.
void vgaRestoreTextMode(void);
// Wait for vertical retrace. Spins on Input Status 1 bit 3.
// Useful for timing-sensitive register writes and tear-free updates.
void vgaWaitVRetrace(void);
// Enable/disable VGA display output by toggling sequencer clocking
// mode bit 5. Used during mode transitions to prevent screen garbage.
void vgaBlankScreen(bool blank);
#endif // VGA_COMMON_H