/* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. * * This file is part of the 86Box distribution. * * Emulation of the old and new IBM CGA graphics cards. * * * * Authors: Sarah Walker, * Miran Grca, , * Connor Hyde / starfrost, * * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. * Copyright 2025 starfrost (refactoring) */ #ifndef VIDEO_CGA_H #define VIDEO_CGA_H // Mode flags for the CGA. // Set by writing to 3D8 typedef enum cga_mode_flags_e { CGA_MODE_FLAG_HIGHRES = 1 << 0, // 80-column text mode CGA_MODE_FLAG_GRAPHICS = 1 << 1, // Graphics mode CGA_MODE_FLAG_BW = 1 << 2, // Black and white CGA_MODE_FLAG_VIDEO_ENABLE = 1 << 3, // 0 = no video (as if the video was 0) CGA_MODE_FLAG_HIGHRES_GRAPHICS = 1 << 4, // 640*200 mode. Corrupts text mode if CGA_MODE_FLAG_GRAPHICS not set. CGA_MODE_FLAG_BLINK = 1 << 5, // If this is set, bit 5 of textmode characters blinks. Otherwise it is a high-intensity bg mode. } cga_mode_flags; // Motorola MC6845 CRTC registers typedef enum cga_crtc_registers_e { CGA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync) CGA_CRTC_HDISP = 0x1, // Horizontal display CGA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc CGA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync CGA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync) CGA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value CGA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline) CGA_CRTC_VSYNC = 0x7, // Vertical sync scanline number CGA_CRTC_INTERLACE = 0x8, // Interlacing mode CGA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address CGA_CRTC_CURSOR_START = 0xA, // Cursor start scanline CGA_CRTC_CURSOR_END = 0xB, // Cursor end scanline CGA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits CGA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits CGA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits CGA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits CGA_CRTC_LIGHT_PEN_ADDR_HIGH = 0x10, // Light pen address high 8 bits (not currently supported) CGA_CRTC_LIGHT_PEN_ADDR_LOW = 0x11, // Light pen address low 8 bits (not currently supported) } cga_crtc_registers; // Registers for the CGA typedef enum cga_registers_e { CGA_REGISTER_CRTC_INDEX = 0x3D4, CGA_REGISTER_CRTC_DATA = 0x3D5, CGA_REGISTER_MODE_CONTROL = 0x3D8, CGA_REGISTER_COLOR_SELECT = 0x3D9, CGA_REGISTER_STATUS = 0x3DA, CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH = 0x3DB, CGA_REGISTER_SET_LIGHT_PEN_LATCH = 0x3DC, } cga_registers; #define CGA_NUM_CRTC_REGS 32 typedef struct cga_t { mem_mapping_t mapping; int crtcreg; uint8_t crtc[CGA_NUM_CRTC_REGS]; uint8_t cgastat; uint8_t cgamode; uint8_t cgacol; uint8_t lp_strobe; int fontbase; int linepos; int displine; int scanline; int vc; int cgadispon; int cursorvisible; // Determines if the cursor is visible FOR THE CURRENT SCANLINE. int cursoron; int cgablink; int vsynctime; int vadj; uint16_t memaddr; uint16_t memaddr_backup; int oddeven; uint64_t dispontime; uint64_t dispofftime; pc_timer_t timer; int firstline; int lastline; int drawcursor; int fullchange; uint8_t *vram; uint8_t charbuffer[256]; int revision; int composite; int snow_enabled; int rgb_type; int double_type; } cga_t; void cga_init(cga_t *cga); void cga_out(uint16_t addr, uint8_t val, void *priv); uint8_t cga_in(uint16_t addr, void *priv); void cga_write(uint32_t addr, uint8_t val, void *priv); uint8_t cga_read(uint32_t addr, void *priv); void cga_recalctimings(cga_t *cga); void cga_poll(void *priv); #ifdef EMU_DEVICE_H extern const device_config_t cga_config[]; extern const device_t cga_device; extern const device_t cga_pravetz_device; #endif #endif /*VIDEO_CGA_H*/