diff --git a/src/include/86box/m_pcjr.h b/src/include/86box/m_pcjr.h index 3ffcc3b3e..7a137fb03 100644 --- a/src/include/86box/m_pcjr.h +++ b/src/include/86box/m_pcjr.h @@ -30,7 +30,7 @@ typedef struct pcjr_s uint8_t array[32]; int array_ff; int memctrl; - uint8_t stat; + uint8_t status; int addr_mode; uint8_t *vram; uint8_t *b8000; diff --git a/src/include/86box/m_tandy.h b/src/include/86box/m_tandy.h index 392c9b8a5..2d0100c1a 100644 --- a/src/include/86box/m_tandy.h +++ b/src/include/86box/m_tandy.h @@ -27,7 +27,7 @@ typedef struct t1kvid_t { int memctrl; uint8_t mode; uint8_t col; - uint8_t stat; + uint8_t status; uint8_t *vram; uint8_t *b8000; diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 6c88d50e6..7cd29aa08 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -39,7 +39,7 @@ typedef struct ega_t { uint8_t lb; uint8_t lc; uint8_t ld; - uint8_t stat; + uint8_t status; uint8_t colourcompare; uint8_t colournocare; uint8_t scrblank; diff --git a/src/include/86box/vid_hercules.h b/src/include/86box/vid_hercules.h index c2d2770a9..3d9324124 100644 --- a/src/include/86box/vid_hercules.h +++ b/src/include/86box/vid_hercules.h @@ -31,7 +31,7 @@ typedef struct { uint8_t ctrl; uint8_t ctrl2; - uint8_t stat; + uint8_t status; uint64_t dispontime; uint64_t dispofftime; diff --git a/src/include/86box/vid_mda.h b/src/include/86box/vid_mda.h index 44123ce52..4cd7e2c54 100644 --- a/src/include/86box/vid_mda.h +++ b/src/include/86box/vid_mda.h @@ -1,18 +1,78 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 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 IBM Monochrome Display and Printer card. + * + * Authors: Sarah Walker, starfrost + * + * Copyright 2007-2024 Sarah Walker + * Copyright 2025 Connor Hyde / starfrost, + */ #ifndef VIDEO_MDA_H #define VIDEO_MDA_H +// Defines +#define MDA_CRTC_NUM_REGISTERS 32 + +// Enums & structures + +typedef enum mda_registers_e +{ + MDA_REGISTER_START = 0x3B0, + + MDA_REGISTER_CRTC_INDEX = 0x3B4, + MDA_REGISTER_CRTC_DATA = 0x3B5, + MDA_REGISTER_MODE_CONTROL = 0x3B8, + MDA_REGISTER_CRT_STATUS = 0x3BA, + MDA_REGISTER_PARALLEL_DATA = 0x3BC, + MDA_REGISTER_PRINTER_STATUS = 0x3BD, + MDA_REGISTER_PRINTER_CONTROL = 0x3BE, + + MDA_REGISTER_END = 0x3BF, +} mda_registers; + +// Motorola MC6845 CRTC registers (without light pen for some reason) +typedef enum mda_crtc_registers_e +{ + MDA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync) + MDA_CRTC_HDISP = 0x1, // Horizontal display + MDA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc + MDA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync + MDA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync) + MDA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value + MDA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline) + MDA_CRTC_VSYNC = 0x7, // Vertical sync scanline number + MDA_CRTC_INTERLACE = 0x8, // Interlacing mode + MDA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address + MDA_CRTC_CURSOR_START = 0xA, // Cursor start scanline + MDA_CRTC_CURSOR_END = 0xB, // Cursor end scanline + MDA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits + MDA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits + MDA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits + MDA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits +} mda_crtc_registers; + +typedef enum mda_mode_flags_e +{ + MDA_MODE_HIGHRES = 1 << 0, + MDA_MODE_VIDEO_ENABLE = 1 << 3, + MDA_MODE_BLINK = 1 << 5, +} mda_mode_flags; + typedef struct mda_t { mem_mapping_t mapping; - uint8_t crtc[32]; + uint8_t crtc[MDA_CRTC_NUM_REGISTERS]; int crtcreg; - uint8_t ctrl; - uint8_t stat; + uint8_t mode; + uint8_t status; uint64_t dispontime; uint64_t dispofftime; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 0c39c2176..584b7b3ac 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -105,7 +105,7 @@ typedef struct amsvid_t { int cga_enabled; /* 1640 */ uint8_t cgacol; uint8_t cgamode; - uint8_t stat; + uint8_t status; uint8_t plane_write; /* 1512/200 */ uint8_t plane_read; /* 1512/200 */ uint8_t border; /* 1512/200 */ @@ -290,7 +290,7 @@ vid_in_1512(uint16_t addr, void *priv) break; case 0x03da: - ret = vid->stat; + ret = vid->status; break; default: @@ -357,7 +357,7 @@ vid_poll_1512(void *priv) if (!vid->linepos) { timer_advance_u64(&vid->timer, vid->dispofftime); - vid->stat |= 1; + vid->status |= 1; vid->linepos = 1; scanline_old = vid->scanline; if (vid->dispon) { @@ -496,7 +496,7 @@ vid_poll_1512(void *priv) vid->scanline = scanline_old; if (vid->vsynctime) - vid->stat |= 8; + vid->status |= 8; vid->displine++; if (vid->displine >= 360) vid->displine = 0; @@ -505,12 +505,12 @@ vid_poll_1512(void *priv) if ((vid->lastline - vid->firstline) == 199) vid->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ if (vid->dispon) - vid->stat &= ~1; + vid->status &= ~1; vid->linepos = 0; if (vid->vsynctime) { vid->vsynctime--; if (!vid->vsynctime) - vid->stat &= ~8; + vid->status &= ~8; } if (vid->scanline == (vid->crtc[11] & 31)) { vid->cursorvisible = 0; @@ -1044,7 +1044,7 @@ vid_in_200(uint16_t addr, void *priv) switch (addr) { case 0x03b8: - return (mda->ctrl); + return (mda->mode); case 0x03d8: return (cga->cgamode); @@ -1106,9 +1106,9 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) } return; case 0x3b8: - old = mda->ctrl; - mda->ctrl = val; - if ((mda->ctrl ^ old) & 3) + old = mda->mode; + mda->mode = val; + if ((mda->mode ^ old) & 3) mda_recalctimings(mda); vid->crtc_index &= 0x1F; vid->crtc_index |= 0x80; @@ -1269,7 +1269,7 @@ static void lcdm_poll(amsvid_t *vid) { mda_t *mda = &vid->mda; - uint16_t cursoraddr = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; int drawcursor; int x; int oldvc; @@ -1280,42 +1280,42 @@ lcdm_poll(amsvid_t *vid) if (!mda->linepos) { timer_advance_u64(&vid->timer, mda->dispofftime); - mda->stat |= 1; + mda->status |= 1; mda->linepos = 1; scanline_old = mda->scanline; - if ((mda->crtc[8] & 3) == 3) + if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3) mda->scanline = (mda->scanline << 1) & 7; if (mda->dispon) { if (mda->displine < mda->firstline) mda->firstline = mda->displine; mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { + for (x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) { chr = mda->vram[(mda->memaddr<< 1) & 0xfff]; attr = mda->vram[((mda->memaddr<< 1) + 1) & 0xfff]; drawcursor = ((mda->memaddr== cursoraddr) && mda->cursorvisible && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->scanline, 0, mda->ctrl); + lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->scanline, 0, mda->mode); mda->memaddr++; } } mda->scanline = scanline_old; - if (mda->vc == mda->crtc[7] && !mda->scanline) - mda->stat |= 8; + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline) + mda->status |= 8; mda->displine++; if (mda->displine >= 500) mda->displine = 0; } else { timer_advance_u64(&vid->timer, mda->dispontime); if (mda->dispon) - mda->stat &= ~1; + mda->status &= ~1; mda->linepos = 0; if (mda->vsynctime) { mda->vsynctime--; if (!mda->vsynctime) - mda->stat &= ~8; + mda->status &= ~8; } - if (mda->scanline == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->scanline == ((mda->crtc[11] & 31) >> 1))) { + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) { mda->cursorvisible = 0; } if (mda->vadj) { @@ -1325,35 +1325,35 @@ lcdm_poll(amsvid_t *vid) mda->vadj--; if (!mda->vadj) { mda->dispon = 1; - mda->memaddr= mda->memaddr_backup = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; mda->scanline = 0; } - } else if (mda->scanline == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->scanline == (mda->crtc[9] >> 1))) { + } else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { mda->memaddr_backup = mda->memaddr; mda->scanline = 0; oldvc = mda->vc; mda->vc++; mda->vc &= 127; - if (mda->vc == mda->crtc[6]) + if (mda->vc == mda->crtc[MDA_CRTC_VDISP]) mda->dispon = 0; - if (oldvc == mda->crtc[4]) { + if (oldvc == mda->crtc[MDA_CRTC_VTOTAL]) { mda->vc = 0; - mda->vadj = mda->crtc[5]; + mda->vadj = mda->crtc[MDA_CRTC_VTOTAL_ADJUST]; if (!mda->vadj) mda->dispon = 1; if (!mda->vadj) - mda->memaddr= mda->memaddr_backup = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) + mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((mda->crtc[MDA_CRTC_CURSOR_START] & 0x60) == 0x20) mda->cursoron = 0; else mda->cursoron = mda->blink & 16; } - if (mda->vc == mda->crtc[7]) { + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC]) { mda->dispon = 0; mda->displine = 0; mda->vsynctime = 16; - if (mda->crtc[7]) { - x = mda->crtc[1] * 8; + if (mda->crtc[MDA_CRTC_VSYNC]) { + x = mda->crtc[MDA_CRTC_HDISP] * 8; mda->lastline++; if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) { xsize = x; @@ -1369,8 +1369,8 @@ lcdm_poll(amsvid_t *vid) } video_blit_memtoscreen(0, mda->firstline, xsize, ysize); frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; + video_res_x = mda->crtc[MDA_CRTC_HDISP]; + video_res_y = mda->crtc[MDA_CRTC_VDISP]; video_bpp = 0; } mda->firstline = 1000; @@ -1382,7 +1382,7 @@ lcdm_poll(amsvid_t *vid) mda->scanline &= 31; mda->memaddr= mda->memaddr_backup; } - if (mda->scanline == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->scanline == ((mda->crtc[10] & 31) >> 1))) + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) mda->cursorvisible = 1; } } diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index dcac57fe1..97202340d 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -459,7 +459,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x42e8: - ibm8514_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val); + ibm8514_log("VBLANK status=%02x, val=%02x.\n", dev->subsys_stat, val); if (len == 2) { dev->subsys_cntl = val; dev->subsys_stat &= ~val; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 32a1c2b9e..9dd736cd7 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -3297,7 +3297,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x42e8: case 0x42e9: - mach_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val); + mach_log("VBLANK status=%02x, val=%02x.\n", dev->subsys_stat, val); if (len == 2) dev->subsys_cntl = val; else { diff --git a/src/video/vid_cga_toshiba_t3100e.c b/src/video/vid_cga_toshiba_t3100e.c index 9f7c2f526..e3eb673c8 100644 --- a/src/video/vid_cga_toshiba_t3100e.c +++ b/src/video/vid_cga_toshiba_t3100e.c @@ -169,8 +169,8 @@ t3100e_out(uint16_t addr, uint8_t val, void *priv) t3100e_recalctimings(t3100e); return; - case 0x3D8: /* CGA control register */ - case 0x3D9: /* CGA colour register */ + case CGA_REGISTER_MODE_CONTROL: /* CGA control register */ + case CGA_REGISTER_COLOR_SELECT: /* CGA colour register */ cga_out(addr, val, &t3100e->cga); return; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 3b4e8cce0..d937b2458 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -505,7 +505,7 @@ ega_in(uint16_t addr, void *priv) case 0x3da: ega->attrff = 0; if (type == EGA_TYPE_COMPAQ) { - ret = ega->stat & 0xcf; + ret = ega->status & 0xcf; switch ((ega->attrregs[0x12] >> 4) & 0x03) { case 0x00: /* 00 = Pri. Red (5), Pri. Blue (4) */ @@ -526,8 +526,8 @@ ega_in(uint16_t addr, void *priv) break; } } else { - ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ - ret = ega->stat; + ega->status ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ + ret = ega->status; } break; case 0x7c6: @@ -837,7 +837,7 @@ ega_poll(void *priv) if (!ega->linepos) { timer_advance_u64(&ega->timer, ega->dispofftime); - ega->stat |= 1; + ega->status |= 1; ega->linepos = 1; if (ega->dispon) { @@ -877,8 +877,8 @@ ega_poll(void *priv) ega->displine++; if (ega->interlace) ega->displine++; - if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) - ega->stat &= ~8; + if ((ega->status & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) + ega->status &= ~8; ega->vslines++; if (ega->chipset) { if (ega->hdisp >= 800) { @@ -896,7 +896,7 @@ ega_poll(void *priv) timer_advance_u64(&ega->timer, ega->dispontime); if (ega->dispon) - ega->stat &= ~1; + ega->status &= ~1; ega->hdisp_on = 0; ega->linepos = 0; @@ -968,7 +968,7 @@ ega_poll(void *priv) } if (ega->vc == ega->vsyncstart) { ega->dispon = 0; - ega->stat |= 8; + ega->status |= 8; #if 0 picint(1 << 2); #endif diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 4b8d796a3..5e0ac1bc9 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -178,8 +178,8 @@ hercules_in(uint16_t addr, void *priv) case 0x03ba: ret = 0x70; /* Hercules ident */ ret |= (dev->lp_ff ? 2 : 0); - ret |= (dev->stat & 0x01); - if (dev->stat & 0x08) + ret |= (dev->status & 0x01); + if (dev->status & 0x08) ret |= 0x80; if ((ret & 0x81) == 0x80) ret |= 0x08; @@ -300,7 +300,7 @@ hercules_poll(void *priv) if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; scanline_old = dev->scanline; @@ -380,7 +380,7 @@ hercules_poll(void *priv) dev->scanline = scanline_old; if (dev->vc == dev->crtc[7] && !dev->scanline) - dev->stat |= 8; + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; @@ -388,13 +388,13 @@ hercules_poll(void *priv) timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { diff --git a/src/video/vid_hercules_incolor.c b/src/video/vid_hercules_incolor.c index 6e202d338..c4751e8fa 100644 --- a/src/video/vid_hercules_incolor.c +++ b/src/video/vid_hercules_incolor.c @@ -157,7 +157,7 @@ typedef struct { uint8_t crtc[32]; int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, status; uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -285,7 +285,7 @@ incolor_in(uint16_t port, void *priv) case 0x3ba: /* 0x50: InColor card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x50; + ret = (dev->status & 0xf) | ((dev->status & 8) << 4) | 0x50; break; default: @@ -863,7 +863,7 @@ incolor_poll(void *priv) if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; scanline_old = dev->scanline; if ((dev->crtc[8] & 3) == 3) @@ -882,19 +882,19 @@ incolor_poll(void *priv) } dev->scanline = scanline_old; if (dev->vc == dev->crtc[7] && !dev->scanline) - dev->stat |= 8; + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; } else { timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { diff --git a/src/video/vid_hercules_plus.c b/src/video/vid_hercules_plus.c index 4a2790dc0..0c6125d0b 100644 --- a/src/video/vid_hercules_plus.c +++ b/src/video/vid_hercules_plus.c @@ -67,7 +67,7 @@ typedef struct { uint8_t crtc[32]; int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, status; uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -194,7 +194,7 @@ herculesplus_in(uint16_t port, void *priv) case 0x3ba: /* 0x10: Hercules Plus card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; + ret = (dev->status & 0xf) | ((dev->status & 8) << 4) | 0x10; break; default: @@ -494,7 +494,7 @@ herculesplus_poll(void *priv) VIDEO_MONITOR_PROLOGUE(); if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; scanline_old = dev->scanline; if ((dev->crtc[8] & 3) == 3) @@ -519,19 +519,19 @@ herculesplus_poll(void *priv) } dev->scanline = scanline_old; if (dev->vc == dev->crtc[7] && !dev->scanline) - dev->stat |= 8; + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; } else { timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 4928441e6..c8a739fbe 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -12,9 +12,11 @@ * * Authors: Sarah Walker, * Miran Grca, + * Connor Hyde, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2025 Miran Grca. + * Copyright 2025 starfrost / Connor Hyde */ #include #include @@ -44,32 +46,35 @@ mda_out(uint16_t addr, uint8_t val, void *priv) { mda_t *mda = (mda_t *) priv; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - mda->crtcreg = val & 31; - return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - mda->crtc[mda->crtcreg] = val; - if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - mda->crtc[10] = 0xb; - mda->crtc[11] = 0xc; - } - mda_recalctimings(mda); - return; - case 0x3b8: - mda->ctrl = val; - return; + if (addr < MDA_REGISTER_START + || addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case + return; + switch (addr) + { + case MDA_REGISTER_MODE_CONTROL: + mda->mode = val; + return; default: break; } + + // addr & 1 == 1 = MDA_REGISTER_CRTC_DATA + // otherwise MDA_REGISTER_CRTC_INDEX + if (addr & 1) + { + mda->crtc[mda->crtcreg] = val; + if (mda->crtc[MDA_CRTC_CURSOR_START] == 6 + && mda->crtc[MDA_CRTC_CURSOR_END] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + mda->crtc[MDA_CRTC_CURSOR_START] = 0xb; + mda->crtc[MDA_CRTC_CURSOR_END] = 0xc; + } + mda_recalctimings(mda); + } + else + mda->crtcreg = val & 31; + } uint8_t @@ -77,24 +82,26 @@ mda_in(uint16_t addr, void *priv) { const mda_t *mda = (mda_t *) priv; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - return mda->crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - return mda->crtc[mda->crtcreg]; - case 0x3ba: - return mda->stat | 0xF0; + switch (addr) + { + case MDA_REGISTER_CRT_STATUS: + return mda->status | 0xF0; default: + if (addr < MDA_REGISTER_START + || addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case + return 0xFF; + + // MDA_REGISTER_CRTC_DATA + if (addr & 1) + return mda->crtc[mda->crtcreg]; + else + return mda->crtcreg; + break; } - return 0xff; + + return 0xFF; } void @@ -118,8 +125,8 @@ mda_recalctimings(mda_t *mda) double _dispontime; double _dispofftime; double disptime; - disptime = mda->crtc[0] + 1; - _dispontime = mda->crtc[1]; + disptime = mda->crtc[MDA_CRTC_HTOTAL] + 1; + _dispontime = mda->crtc[MDA_CRTC_HDISP]; _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; @@ -131,7 +138,7 @@ void mda_poll(void *priv) { mda_t *mda = (mda_t *) priv; - uint16_t cursoraddr = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; int drawcursor; int x; int c; @@ -144,10 +151,10 @@ mda_poll(void *priv) VIDEO_MONITOR_PROLOGUE() if (!mda->linepos) { timer_advance_u64(&mda->timer, mda->dispofftime); - mda->stat |= 1; + mda->status |= 1; mda->linepos = 1; scanline_old = mda->scanline; - if ((mda->crtc[8] & 3) == 3) + if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3) mda->scanline = (mda->scanline << 1) & 7; if (mda->dispon) { if (mda->displine < mda->firstline) { @@ -155,11 +162,11 @@ mda_poll(void *priv) video_wait_for_buffer(); } mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { + for (x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) { chr = mda->vram[(mda->memaddr << 1) & 0xfff]; attr = mda->vram[((mda->memaddr << 1) + 1) & 0xfff]; drawcursor = ((mda->memaddr == cursoraddr) && mda->cursorvisible && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor); if (mda->scanline == 12 && ((attr & 7) == 1)) { for (c = 0; c < 9; c++) buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; @@ -178,11 +185,11 @@ mda_poll(void *priv) } } - video_process_8(mda->crtc[1] * 9, mda->displine); + video_process_8(mda->crtc[MDA_CRTC_HDISP] * 9, mda->displine); } mda->scanline = scanline_old; - if (mda->vc == mda->crtc[7] && !mda->scanline) { - mda->stat |= 8; + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline) { + mda->status |= 8; } mda->displine++; if (mda->displine >= 500) @@ -190,15 +197,17 @@ mda_poll(void *priv) } else { timer_advance_u64(&mda->timer, mda->dispontime); if (mda->dispon) - mda->stat &= ~1; + mda->status &= ~1; mda->linepos = 0; if (mda->vsynctime) { mda->vsynctime--; if (!mda->vsynctime) { - mda->stat &= ~8; + mda->status &= ~8; } } - if (mda->scanline == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->scanline == ((mda->crtc[11] & 31) >> 1))) { + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31) + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) { mda->cursorvisible = 0; } if (mda->vadj) { @@ -208,35 +217,37 @@ mda_poll(void *priv) mda->vadj--; if (!mda->vadj) { mda->dispon = 1; - mda->memaddr = mda->memaddr_backup = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; mda->scanline = 0; } - } else if (mda->scanline == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->scanline == (mda->crtc[9] >> 1))) { + } else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { mda->memaddr_backup = mda->memaddr; mda->scanline = 0; oldvc = mda->vc; mda->vc++; mda->vc &= 127; - if (mda->vc == mda->crtc[6]) + if (mda->vc == mda->crtc[MDA_CRTC_VDISP]) mda->dispon = 0; - if (oldvc == mda->crtc[4]) { + if (oldvc == mda->crtc[MDA_CRTC_VTOTAL]) { mda->vc = 0; - mda->vadj = mda->crtc[5]; + mda->vadj = mda->crtc[MDA_CRTC_VTOTAL_ADJUST]; if (!mda->vadj) mda->dispon = 1; if (!mda->vadj) - mda->memaddr = mda->memaddr_backup = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) + mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((mda->crtc[MDA_CRTC_CURSOR_START] & 0x60) == 0x20) mda->cursoron = 0; else mda->cursoron = mda->blink & 16; } - if (mda->vc == mda->crtc[7]) { + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC]) { mda->dispon = 0; mda->displine = 0; mda->vsynctime = 16; - if (mda->crtc[7]) { - x = mda->crtc[1] * 9; + if (mda->crtc[MDA_CRTC_VSYNC]) { + x = mda->crtc[MDA_CRTC_HDISP] * 9; mda->lastline++; if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) { xsize = x; @@ -252,8 +263,8 @@ mda_poll(void *priv) } video_blit_memtoscreen(0, mda->firstline, xsize, ysize); frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; + video_res_x = mda->crtc[MDA_CRTC_HDISP]; + video_res_y = mda->crtc[MDA_CRTC_VDISP]; video_bpp = 0; } mda->firstline = 1000; @@ -265,7 +276,9 @@ mda_poll(void *priv) mda->scanline &= 31; mda->memaddr = mda->memaddr_backup; } - if (mda->scanline == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->scanline == ((mda->crtc[10] & 31) >> 1))) { + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31) + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) { mda->cursorvisible = 1; } } diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index c02275f09..17a43fb40 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -183,8 +183,8 @@ vid_in(uint16_t addr, void *priv) case 0x3da: pcjr->array_ff = 0; - pcjr->stat ^= 0x10; - ret = pcjr->stat; + pcjr->status ^= 0x10; + ret = pcjr->status; break; default: @@ -316,7 +316,7 @@ vid_poll(void *priv) if (!pcjr->linepos) { timer_advance_u64(&pcjr->timer, pcjr->dispofftime); - pcjr->stat &= ~1; + pcjr->status &= ~1; pcjr->linepos = 1; scanline_old = pcjr->scanline; if ((pcjr->crtc[8] & 3) == 3) @@ -557,7 +557,7 @@ vid_poll(void *priv) } pcjr->scanline = scanline_old; if (pcjr->vc == pcjr->crtc[7] && !pcjr->scanline) { - pcjr->stat |= 8; + pcjr->status |= 8; } pcjr->displine++; if (pcjr->displine >= 360) @@ -565,12 +565,12 @@ vid_poll(void *priv) } else { timer_advance_u64(&pcjr->timer, pcjr->dispontime); if (pcjr->dispon) - pcjr->stat |= 1; + pcjr->status |= 1; pcjr->linepos = 0; if (pcjr->vsynctime) { pcjr->vsynctime--; if (!pcjr->vsynctime) { - pcjr->stat &= ~8; + pcjr->status &= ~8; } } if (pcjr->scanline == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == ((pcjr->crtc[11] & 31) >> 1))) { diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c index 78e7d55c3..312527a35 100644 --- a/src/video/vid_tandy.c +++ b/src/video/vid_tandy.c @@ -268,7 +268,7 @@ tandy_vid_in(uint16_t addr, void *priv) break; case 0x03da: - ret = vid->stat; + ret = vid->status; break; case 0x3db: @@ -353,7 +353,7 @@ vid_poll(void *priv) if (!vid->linepos) { timer_advance_u64(&vid->timer, vid->dispofftime); - vid->stat |= 1; + vid->status |= 1; vid->linepos = 1; scanline_old = vid->scanline; if ((vid->crtc[8] & 3) == 3) @@ -574,19 +574,19 @@ vid_poll(void *priv) } vid->scanline = scanline_old; if (vid->vc == vid->crtc[7] && !vid->scanline) - vid->stat |= 8; + vid->status |= 8; vid->displine++; if (vid->displine >= 360) vid->displine = 0; } else { timer_advance_u64(&vid->timer, vid->dispontime); if (vid->dispon) - vid->stat &= ~1; + vid->status &= ~1; vid->linepos = 0; if (vid->vsynctime) { vid->vsynctime--; if (!vid->vsynctime) - vid->stat &= ~8; + vid->status &= ~8; } if (vid->scanline == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->scanline == ((vid->crtc[11] & 31) >> 1))) { vid->cursorvisible = 0;