mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 09:35:32 -07:00
Merge branch 'master' into vmm
This commit is contained in:
@@ -57,6 +57,7 @@ add_library(dev OBJECT
|
||||
smbus_ali7101.c
|
||||
smbus_piix4.c
|
||||
smbus_sis5595.c
|
||||
tulip_jumper.c
|
||||
unittester.c
|
||||
)
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ isarom_init(const device_t *info)
|
||||
static const device_config_t isarom_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File",
|
||||
.description = "BIOS file",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -234,7 +234,7 @@ static const device_config_t isarom_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.description = "BIOS size",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -260,7 +260,7 @@ static const device_config_t isarom_config[] = {
|
||||
static const device_config_t isarom_dual_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File (ROM #1)",
|
||||
.description = "BIOS file (ROM #1)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -271,7 +271,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address (ROM #1)",
|
||||
.description = "BIOS address (ROM #1)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -282,7 +282,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size (ROM #1):",
|
||||
.description = "BIOS size (ROM #1)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -304,7 +304,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn2",
|
||||
.description = "BIOS File (ROM #2)",
|
||||
.description = "BIOS file (ROM #2)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -315,7 +315,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr2",
|
||||
.description = "BIOS Address (ROM #2)",
|
||||
.description = "BIOS address (ROM #2)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -326,7 +326,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size2",
|
||||
.description = "BIOS Size (ROM #2):",
|
||||
.description = "BIOS size (ROM #2)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -352,7 +352,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
static const device_config_t isarom_quad_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File (ROM #1)",
|
||||
.description = "BIOS file (ROM #1)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -363,7 +363,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address (ROM #1)",
|
||||
.description = "BIOS address (ROM #1)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -374,7 +374,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size (ROM #1):",
|
||||
.description = "BIOS size (ROM #1)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -396,7 +396,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn2",
|
||||
.description = "BIOS File (ROM #2)",
|
||||
.description = "BIOS file (ROM #2)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -407,7 +407,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr2",
|
||||
.description = "BIOS Address (ROM #2)",
|
||||
.description = "BIOS address (ROM #2)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -418,7 +418,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size2",
|
||||
.description = "BIOS Size (ROM #2):",
|
||||
.description = "BIOS size (ROM #2)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -440,7 +440,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn3",
|
||||
.description = "BIOS File (ROM #3)",
|
||||
.description = "BIOS file (ROM #3)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -451,7 +451,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr3",
|
||||
.description = "BIOS Address (ROM #3)",
|
||||
.description = "BIOS address (ROM #3)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -462,7 +462,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size3",
|
||||
.description = "BIOS Size (ROM #3):",
|
||||
.description = "BIOS size (ROM #3)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -484,7 +484,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn4",
|
||||
.description = "BIOS File (ROM #4)",
|
||||
.description = "BIOS file (ROM #4)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -495,7 +495,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr4",
|
||||
.description = "BIOS Address (ROM #4)",
|
||||
.description = "BIOS address (ROM #4)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -506,7 +506,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size4",
|
||||
.description = "BIOS Size (ROM #4):",
|
||||
.description = "BIOS size (ROM #4)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@ static const device_config_t keycard_config[] = {
|
||||
};
|
||||
|
||||
const device_t novell_keycard_device = {
|
||||
.name = "Novell Netware 2.x Key Card",
|
||||
.name = "Novell NetWare 2.x Key Card",
|
||||
.internal_name = "mssystems",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
|
||||
103
src/device/tulip_jumper.c
Normal file
103
src/device/tulip_jumper.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the Tulip Jumper Readout.
|
||||
*
|
||||
* Bits 7-5 = board number, 0-5 valid, 6, 7 invalid.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
typedef struct tulip_jumper_t {
|
||||
uint8_t jumper;
|
||||
} tulip_jumper_t;
|
||||
|
||||
#ifdef ENABLE_TULIP_JUMPER_LOG
|
||||
int tulip_jumper_do_log = ENABLE_TULIP_JUMPER_LOG;
|
||||
|
||||
static void
|
||||
tulip_jumper_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (tulip_jumper_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define tulip_jumper_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static uint8_t
|
||||
tulip_jumper_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const tulip_jumper_t *dev = (tulip_jumper_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
tulip_jumper_log("Tulip Jumper: Read %02x\n", dev->jumper);
|
||||
|
||||
ret = dev->jumper;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
tulip_jumper_close(void *priv)
|
||||
{
|
||||
tulip_jumper_t *dev = (tulip_jumper_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
tulip_jumper_init(const device_t *info)
|
||||
{
|
||||
tulip_jumper_t *dev = (tulip_jumper_t *) calloc(1, sizeof(tulip_jumper_t));
|
||||
|
||||
/* Return board number 05. */
|
||||
dev->jumper = 0xbf;
|
||||
|
||||
io_sethandler(0x0d80, 0x0001, tulip_jumper_read, NULL, NULL, NULL, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t tulip_jumper_device = {
|
||||
.name = "Tulip Jumper Readout",
|
||||
.internal_name = "tulip_jumper",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = tulip_jumper_init,
|
||||
.close = tulip_jumper_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -187,10 +187,18 @@ fdc_ctrl_reset(void *priv)
|
||||
fdc->stat = 0x80;
|
||||
fdc->pnum = fdc->ptot = 0;
|
||||
fdc->st0 = 0;
|
||||
fdc->lock = 0;
|
||||
fdc->head = 0;
|
||||
fdc->step = 0;
|
||||
fdc->power_down = 0;
|
||||
|
||||
if (!fdc->lock) {
|
||||
fdc->fifo = 0;
|
||||
fdc->tfifo = 1;
|
||||
|
||||
fifo_reset(fdc->fifo_p);
|
||||
fifo_set_len(fdc->fifo_p, fdc->tfifo + 1);
|
||||
fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1);
|
||||
}
|
||||
}
|
||||
|
||||
sector_id_t
|
||||
@@ -2374,6 +2382,8 @@ fdc_reset(void *priv)
|
||||
fdc->swwp = 0;
|
||||
fdc->disable_write = 0;
|
||||
|
||||
fdc->lock = 0;
|
||||
|
||||
fdc_ctrl_reset(fdc);
|
||||
|
||||
if (!(fdc->flags & FDC_FLAG_AT))
|
||||
|
||||
@@ -183,7 +183,7 @@ static const device_config_t monster_fdc_config[] = {
|
||||
#if 0
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.description = "BIOS size",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 32,
|
||||
|
||||
@@ -201,6 +201,8 @@ extern const device_t vlsi_scamp_device;
|
||||
extern const device_t wd76c10_device;
|
||||
|
||||
/* Miscellaneous Hardware */
|
||||
extern const device_t tulip_jumper_device;
|
||||
|
||||
extern const device_t dell_jumper_device;
|
||||
|
||||
extern const device_t nec_mate_unk_device;
|
||||
|
||||
72
src/include/86box/m_pcjr.h
Normal file
72
src/include/86box/m_pcjr.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header files for the PCjr keyboard and video subsystems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
|
||||
typedef struct pcjr_s
|
||||
{
|
||||
/* Video Controller stuff. */
|
||||
mem_mapping_t mapping;
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
int array_index;
|
||||
uint8_t array[32];
|
||||
int array_ff;
|
||||
int memctrl;
|
||||
uint8_t status;
|
||||
int addr_mode;
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
int linepos;
|
||||
int displine;
|
||||
int scanline;
|
||||
int vc;
|
||||
int dispon;
|
||||
int cursorvisible; // Is the cursor visible on the current scanline?
|
||||
int cursoron;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
int composite;
|
||||
int apply_hd;
|
||||
|
||||
/* Keyboard Controller stuff. */
|
||||
int latched;
|
||||
int data;
|
||||
int serial_data[44];
|
||||
int serial_pos;
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
pc_timer_t send_delay_timer;
|
||||
|
||||
} pcjr_t;
|
||||
|
||||
void pcjr_recalc_timings(pcjr_t *pcjr);
|
||||
|
||||
// Note: This is a temporary solution until the pcjr video is made its own gfx card
|
||||
void pcjr_vid_init(pcjr_t *pcjr);
|
||||
95
src/include/86box/m_tandy.h
Normal file
95
src/include/86box/m_tandy.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header files for the Tandy keyboard and video subsystems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
typedef struct t1kvid_t {
|
||||
mem_mapping_t mapping;
|
||||
mem_mapping_t vram_mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
int array_index;
|
||||
uint8_t array[256];
|
||||
int memctrl;
|
||||
uint8_t mode;
|
||||
uint8_t col;
|
||||
uint8_t status;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
uint32_t b8000_mask;
|
||||
uint32_t b8000_limit;
|
||||
uint8_t planar_ctrl;
|
||||
uint8_t lp_strobe;
|
||||
|
||||
int linepos;
|
||||
int displine;
|
||||
int scanline;
|
||||
int vc;
|
||||
int dispon;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int fullchange;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
|
||||
int composite;
|
||||
} t1kvid_t;
|
||||
|
||||
typedef struct t1keep_t {
|
||||
char *path;
|
||||
|
||||
int state;
|
||||
int count;
|
||||
int addr;
|
||||
int clk;
|
||||
uint16_t data;
|
||||
uint16_t store[64];
|
||||
} t1keep_t;
|
||||
|
||||
typedef struct tandy_t {
|
||||
mem_mapping_t ram_mapping;
|
||||
mem_mapping_t rom_mapping; /* SL2 */
|
||||
|
||||
uint8_t *rom; /* SL2 */
|
||||
uint8_t ram_bank;
|
||||
uint8_t rom_bank; /* SL2 */
|
||||
int rom_offset; /* SL2 */
|
||||
|
||||
uint32_t base;
|
||||
uint32_t mask;
|
||||
int is_hx;
|
||||
int is_sl2;
|
||||
|
||||
t1kvid_t *vid;
|
||||
} tandy_t;
|
||||
|
||||
void tandy_vid_init(tandy_t* dev);
|
||||
uint8_t tandy_vid_in(uint16_t addr, void* priv);
|
||||
void tandy_vid_out(uint16_t addr, uint8_t val, void *priv);
|
||||
|
||||
void tandy_vid_close(void* priv);
|
||||
void tandy_recalc_address_sl(tandy_t* dev); //this function is needed by both m_ and vid_tandy.c
|
||||
@@ -473,7 +473,9 @@ extern int machine_at_spc4216p_init(const machine_t *);
|
||||
extern int machine_at_spc4620p_init(const machine_t *);
|
||||
extern int machine_at_kmxc02_init(const machine_t *);
|
||||
extern int machine_at_deskmaster286_init(const machine_t *);
|
||||
|
||||
extern int machine_at_dells200_init(const machine_t *);
|
||||
extern int machine_at_tuliptc7_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pc8_init(const machine_t *);
|
||||
extern int machine_at_3302_init(const machine_t *);
|
||||
@@ -546,6 +548,7 @@ extern int machine_at_exp4349_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vect486vl_init(const machine_t *);
|
||||
extern int machine_at_d824_init(const machine_t *);
|
||||
extern int machine_at_tuliptc38_init(const machine_t *);
|
||||
extern int machine_at_martin_init(const machine_t *);
|
||||
|
||||
extern int machine_at_403tg_init(const machine_t *);
|
||||
@@ -610,6 +613,7 @@ extern int machine_at_iach488_init(const machine_t *);
|
||||
extern int machine_at_pcm9340_init(const machine_t *);
|
||||
extern int machine_at_pcm5330_init(const machine_t *);
|
||||
|
||||
extern int machine_at_84xxuuda_init(const machine_t *);
|
||||
extern int machine_at_ecs486_init(const machine_t *);
|
||||
extern int machine_at_hot433a_init(const machine_t *);
|
||||
extern int machine_at_pl4600c_init(const machine_t *);
|
||||
|
||||
@@ -102,4 +102,6 @@ extern int picinterrupt(void);
|
||||
|
||||
extern uint8_t pic_irq_ack(void);
|
||||
|
||||
extern void pic_toggle_latch(int is_ps2);
|
||||
|
||||
#endif /*EMU_PIC_H*/
|
||||
|
||||
@@ -24,6 +24,19 @@
|
||||
#define INT_FIFO_EMP (1 << 3)
|
||||
#define INT_MASK 0xf
|
||||
|
||||
typedef enum {
|
||||
IBM_8514A_TYPE = 0,
|
||||
ATI_38800_TYPE,
|
||||
ATI_68800_TYPE,
|
||||
TYPE_MAX
|
||||
} ibm8514_card_type;
|
||||
|
||||
typedef enum {
|
||||
IBM = 0,
|
||||
ATI,
|
||||
EXTENSIONS_MAX
|
||||
} ibm8514_extensions_t;
|
||||
|
||||
typedef struct hwcursor8514_t {
|
||||
int ena;
|
||||
int x;
|
||||
@@ -58,7 +71,7 @@ typedef struct ibm8514_t {
|
||||
|
||||
int force_old_addr;
|
||||
int type;
|
||||
int local;
|
||||
ibm8514_card_type local;
|
||||
int bpp;
|
||||
int on;
|
||||
int accel_bpp;
|
||||
@@ -67,7 +80,7 @@ typedef struct ibm8514_t {
|
||||
uint32_t vram_mask;
|
||||
uint32_t pallook[512];
|
||||
uint32_t bios_addr;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
|
||||
PALETTE vgapal;
|
||||
uint8_t hwcursor_oddeven;
|
||||
@@ -207,8 +220,8 @@ typedef struct ibm8514_t {
|
||||
int lastline_draw;
|
||||
int displine;
|
||||
int fullchange;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *changedvram;
|
||||
@@ -223,7 +236,7 @@ typedef struct ibm8514_t {
|
||||
int hdisp;
|
||||
int hdisp2;
|
||||
int hdisped;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vsyncstart;
|
||||
int vsyncwidth;
|
||||
int vtotal;
|
||||
@@ -246,7 +259,8 @@ typedef struct ibm8514_t {
|
||||
int pitch;
|
||||
int ext_pitch;
|
||||
int ext_crt_pitch;
|
||||
int extensions;
|
||||
ibm8514_extensions_t extensions;
|
||||
int onboard;
|
||||
int linear;
|
||||
uint32_t vram_amount;
|
||||
int vram_512k_8514;
|
||||
@@ -263,9 +277,9 @@ typedef struct ibm8514_t {
|
||||
|
||||
} ibm8514_t;
|
||||
|
||||
#define IBM_8514A (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x00))
|
||||
#define ATI_8514A_ULTRA (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x01))
|
||||
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == 0x01)
|
||||
#define ATI_MACH32 ((dev->local & 0xff) == 0x02)
|
||||
#define IBM_8514A (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == IBM))
|
||||
#define ATI_8514A_ULTRA (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == ATI))
|
||||
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == ATI_38800_TYPE)
|
||||
#define ATI_MACH32 ((dev->local & 0xff) == ATI_68800_TYPE)
|
||||
|
||||
#endif /*VIDEO_8514A_H*/
|
||||
|
||||
@@ -137,6 +137,7 @@ typedef struct mach_t {
|
||||
int16_t dx_end;
|
||||
int16_t dy;
|
||||
int16_t dy_end;
|
||||
int16_t dx_first_row_start;
|
||||
int16_t dx_start;
|
||||
int16_t dy_start;
|
||||
int16_t cy;
|
||||
|
||||
@@ -11,20 +11,71 @@
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>,
|
||||
* Connor Hyde / starfrost, <mario64crashed@gmail.com>
|
||||
*
|
||||
* 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[32];
|
||||
uint8_t crtc[CGA_NUM_CRTC_REGS];
|
||||
|
||||
uint8_t cgastat;
|
||||
|
||||
@@ -36,17 +87,16 @@ typedef struct cga_t {
|
||||
int fontbase;
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int coff;
|
||||
int cursorvisible; // Determines if the cursor is visible FOR THE CURRENT SCANLINE.
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int oddeven;
|
||||
|
||||
uint64_t dispontime;
|
||||
|
||||
@@ -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;
|
||||
@@ -68,12 +68,12 @@ typedef struct ega_t {
|
||||
int chain4;
|
||||
int chain2_read;
|
||||
int chain2_write;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int oddeven_page;
|
||||
int oddeven_chain;
|
||||
int vc;
|
||||
int real_vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
int cursoron;
|
||||
@@ -115,14 +115,14 @@ typedef struct ega_t {
|
||||
int chipset;
|
||||
int mono_display;
|
||||
|
||||
int mdacols[256][2][2];
|
||||
int mda_attr_to_color_table[256][2][2];
|
||||
|
||||
uint32_t charseta;
|
||||
uint32_t charsetb;
|
||||
uint32_t ma_latch;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t ca;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t cursoraddr;
|
||||
uint32_t vram_limit;
|
||||
uint32_t overscan_color;
|
||||
uint32_t cca;
|
||||
@@ -189,11 +189,11 @@ extern void ega_set_type(void *priv, uint32_t local);
|
||||
extern int firstline_draw;
|
||||
extern int lastline_draw;
|
||||
extern int displine;
|
||||
extern int sc;
|
||||
extern int scanline;
|
||||
|
||||
extern uint32_t ma;
|
||||
extern uint32_t ca;
|
||||
extern int con;
|
||||
extern uint32_t memaddr;
|
||||
extern uint32_t cursoraddr;
|
||||
extern int cursorvisible;
|
||||
extern int cursoron;
|
||||
extern int cgablink;
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
} \
|
||||
\
|
||||
if (nr & VAR_ROW0_MA13) \
|
||||
out_addr = (out_addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); \
|
||||
out_addr = (out_addr & ~0x8000) | ((ega->scanline & 1) ? 0x8000 : 0); \
|
||||
if (nr & VAR_ROW1_MA14) \
|
||||
out_addr = (out_addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); \
|
||||
out_addr = (out_addr & ~0x10000) | ((ega->scanline & 2) ? 0x10000 : 0); \
|
||||
\
|
||||
return out_addr; \
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Connor Hyde / starfrost, <mario64crashed@gmail.com
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2021 Jasmine Iwanek.
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
#ifndef VIDEO_HERCULES_H
|
||||
@@ -31,7 +33,7 @@ typedef struct {
|
||||
|
||||
uint8_t ctrl;
|
||||
uint8_t ctrl2;
|
||||
uint8_t stat;
|
||||
uint8_t status;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
@@ -43,21 +45,20 @@ typedef struct {
|
||||
int linepos;
|
||||
int displine;
|
||||
int vc;
|
||||
int sc;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
int con;
|
||||
int coff;
|
||||
int scanline;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int dispon;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
|
||||
int lp_ff;
|
||||
int fullchange;
|
||||
int lp_ff;
|
||||
int fullchange;
|
||||
|
||||
int cols[256][2][2];
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t *vram;
|
||||
int monitor_index;
|
||||
|
||||
@@ -1,42 +1,123 @@
|
||||
/* 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, <mario64crashed@gmail.com>
|
||||
*/
|
||||
|
||||
#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, // MUST be enabled for sane operation
|
||||
MDA_MODE_BW = 1 << 1, // UNUSED in most cases. Not present on Hercules
|
||||
MDA_MODE_VIDEO_ENABLE = 1 << 3,
|
||||
MDA_MODE_BLINK = 1 << 5,
|
||||
} mda_mode_flags;
|
||||
|
||||
typedef enum mda_colors_e
|
||||
{
|
||||
MDA_COLOR_BLACK = 0,
|
||||
MDA_COLOR_BLUE = 1,
|
||||
MDA_COLOR_GREEN = 2,
|
||||
MDA_COLOR_CYAN = 3,
|
||||
MDA_COLOR_RED = 4,
|
||||
MDA_COLOR_MAGENTA = 5,
|
||||
MDA_COLOR_BROWN = 6,
|
||||
MDA_COLOR_WHITE = 7,
|
||||
MDA_COLOR_GREY = 8,
|
||||
MDA_COLOR_BRIGHT_BLUE = 9,
|
||||
MDA_COLOR_BRIGHT_GREEN = 10,
|
||||
MDA_COLOR_BRIGHT_CYAN = 11,
|
||||
MDA_COLOR_BRIGHT_RED = 12,
|
||||
MDA_COLOR_BRIGHT_MAGENTA = 13,
|
||||
MDA_COLOR_BRIGHT_YELLOW = 14,
|
||||
MDA_COLOR_BRIGHT_WHITE = 15,
|
||||
} mda_colors;
|
||||
|
||||
typedef struct mda_t {
|
||||
mem_mapping_t mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
uint8_t crtc[MDA_CRTC_NUM_REGISTERS];
|
||||
int32_t crtcreg;
|
||||
|
||||
uint8_t ctrl;
|
||||
uint8_t stat;
|
||||
uint8_t mode;
|
||||
uint8_t status;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
|
||||
int firstline;
|
||||
int lastline;
|
||||
int32_t firstline;
|
||||
int32_t lastline;
|
||||
|
||||
int fontbase;
|
||||
int linepos;
|
||||
int displine;
|
||||
int vc;
|
||||
int sc;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
int con;
|
||||
int coff;
|
||||
int cursoron;
|
||||
int dispon;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
int monitor_index;
|
||||
int prev_monitor_index;
|
||||
int32_t fontbase;
|
||||
int32_t linepos;
|
||||
int32_t displine;
|
||||
int32_t vc;
|
||||
int32_t scanline;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int32_t cursorvisible;
|
||||
int32_t cursoron;
|
||||
int32_t dispon;
|
||||
int32_t blink;
|
||||
int32_t vsynctime;
|
||||
int32_t vadj;
|
||||
int32_t monitor_index;
|
||||
int32_t prev_monitor_index;
|
||||
int32_t monitor_type; // Used for MDA Colour support (REV0 u64)
|
||||
|
||||
uint8_t *vram;
|
||||
} mda_t;
|
||||
|
||||
@@ -115,14 +115,13 @@ typedef struct pgc {
|
||||
int displine;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int coff;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int oddeven;
|
||||
|
||||
uint64_t dispontime;
|
||||
|
||||
@@ -100,12 +100,12 @@ typedef struct svga_t {
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
int vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int linepos;
|
||||
int vslines;
|
||||
int linecountff;
|
||||
int oddeven;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int scrollcache;
|
||||
@@ -152,15 +152,15 @@ typedef struct svga_t {
|
||||
uint32_t charseta;
|
||||
uint32_t charsetb;
|
||||
uint32_t adv_flags;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t ca_adj;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t write_bank;
|
||||
uint32_t read_bank;
|
||||
uint32_t extra_banks[2];
|
||||
uint32_t banked_mask;
|
||||
uint32_t ca;
|
||||
uint32_t cursoraddr;
|
||||
uint32_t overscan_color;
|
||||
uint32_t *map8;
|
||||
uint32_t pallook[512];
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
extern int firstline_draw;
|
||||
extern int lastline_draw;
|
||||
extern int displine;
|
||||
extern int sc;
|
||||
extern int scanline;
|
||||
|
||||
extern uint32_t ma;
|
||||
extern uint32_t ca;
|
||||
extern int con;
|
||||
extern uint32_t memaddr;
|
||||
extern uint32_t cursoraddr;
|
||||
extern int cursorvisible;
|
||||
extern int cursoron;
|
||||
extern int cgablink;
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
} \
|
||||
\
|
||||
if (nr & VAR_ROW0_MA13) \
|
||||
out_addr = (out_addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); \
|
||||
out_addr = (out_addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); \
|
||||
if (nr & VAR_ROW1_MA14) \
|
||||
out_addr = (out_addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); \
|
||||
out_addr = (out_addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); \
|
||||
\
|
||||
return out_addr; \
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ typedef struct xga_t {
|
||||
int dispon;
|
||||
int h_disp_on;
|
||||
int vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int linepos;
|
||||
int oddeven;
|
||||
int firstline;
|
||||
@@ -160,12 +160,12 @@ typedef struct xga_t {
|
||||
uint32_t hwc_color0;
|
||||
uint32_t hwc_color1;
|
||||
uint32_t disp_start_addr;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t vram_size;
|
||||
uint32_t vram_mask;
|
||||
uint32_t rom_addr;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t read_bank;
|
||||
uint32_t write_bank;
|
||||
uint32_t px_map_base;
|
||||
|
||||
@@ -187,6 +187,10 @@ extern bitmap_t *buffer32;
|
||||
#define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y)
|
||||
#define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x)
|
||||
#define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y)
|
||||
|
||||
#define CGAPAL_CGA_START 16 // Where the 16-color cga text/composite starts
|
||||
|
||||
|
||||
extern PALETTE cgapal;
|
||||
extern PALETTE cgapal_mono[6];
|
||||
#if 0
|
||||
@@ -395,6 +399,7 @@ extern const device_t gd5480_pci_device;
|
||||
/* Compaq CGA */
|
||||
extern const device_t compaq_cga_device;
|
||||
extern const device_t compaq_cga_2_device;
|
||||
extern const device_t compaq_plasma_device;
|
||||
|
||||
/* Olivetti OGC */
|
||||
extern const device_t ogc_device;
|
||||
@@ -609,6 +614,11 @@ extern const device_t velocity_200_agp_device;
|
||||
/* Wyse 700 */
|
||||
extern const device_t wy700_device;
|
||||
|
||||
/* Tandy */
|
||||
extern const device_t tandy_1000_video_device;
|
||||
extern const device_t tandy_1000hx_video_device;
|
||||
extern const device_t tandy_1000sl_video_device;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*EMU_VIDEO_H*/
|
||||
|
||||
@@ -23,7 +23,6 @@ add_library(mch OBJECT
|
||||
m_xt_laserxt.c
|
||||
m_xt_philips.c
|
||||
m_xt_t1000.c
|
||||
m_xt_t1000_vid.c
|
||||
m_xt_xi8088.c
|
||||
m_xt_zenith.c
|
||||
m_pcjr.c
|
||||
@@ -37,7 +36,6 @@ add_library(mch OBJECT
|
||||
m_at_commodore.c
|
||||
m_at_grid.c
|
||||
m_at_t3100e.c
|
||||
m_at_t3100e_vid.c
|
||||
m_ps1.c
|
||||
m_ps1_hdc.c
|
||||
m_ps2_isa.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 */
|
||||
@@ -113,18 +113,17 @@ typedef struct amsvid_t {
|
||||
int fontbase; /* 1512/200 */
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int coff;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int dispon;
|
||||
int blink;
|
||||
uint64_t dispontime; /* 1512/1640 */
|
||||
@@ -291,7 +290,7 @@ vid_in_1512(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
ret = vid->stat;
|
||||
ret = vid->status;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -340,7 +339,7 @@ static void
|
||||
vid_poll_1512(void *priv)
|
||||
{
|
||||
amsvid_t *vid = (amsvid_t *) priv;
|
||||
uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
@@ -354,13 +353,13 @@ vid_poll_1512(void *priv)
|
||||
uint16_t dat4;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
|
||||
if (!vid->linepos) {
|
||||
timer_advance_u64(&vid->timer, vid->dispofftime);
|
||||
vid->stat |= 1;
|
||||
vid->status |= 1;
|
||||
vid->linepos = 1;
|
||||
oldsc = vid->sc;
|
||||
scanline_old = vid->scanline;
|
||||
if (vid->dispon) {
|
||||
if (vid->displine < vid->firstline) {
|
||||
vid->firstline = vid->displine;
|
||||
@@ -370,26 +369,26 @@ vid_poll_1512(void *priv)
|
||||
for (c = 0; c < 8; c++) {
|
||||
if ((vid->cgamode & 0x12) == 0x12) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->border & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->cgacol & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->cgacol & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < 80; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->cgamode & 0x20) {
|
||||
chr = vid->vram[(vid->memaddr<< 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->memaddr== cursoraddr) && vid->cursorvisible && vid->cursoron);
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
@@ -400,21 +399,23 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
}
|
||||
} else if (!(vid->cgamode & 2)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < 40; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->cgamode & 0x20) {
|
||||
chr = vid->vram[(vid->memaddr<< 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->memaddr == cursoraddr)
|
||||
&& vid->cursorvisible && vid->cursoron);
|
||||
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80))
|
||||
@@ -423,21 +424,21 @@ vid_poll_1512(void *priv)
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(vid->cgamode & 16)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
cols[0] = (vid->cgacol & 15) | 16;
|
||||
col = (vid->cgacol & 16) ? 24 : 16;
|
||||
if (vid->cgamode & 4) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BW) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
@@ -451,8 +452,8 @@ vid_poll_1512(void *priv)
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < 40; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
dat = (vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
|
||||
vid->memaddr++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
@@ -460,13 +461,13 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < 40; x++) {
|
||||
ca = ((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000);
|
||||
dat = (vid->vram[ca] << 8) | vid->vram[ca + 1];
|
||||
dat2 = (vid->vram[ca + 0x4000] << 8) | vid->vram[ca + 0x4001];
|
||||
dat3 = (vid->vram[ca + 0x8000] << 8) | vid->vram[ca + 0x8001];
|
||||
dat4 = (vid->vram[ca + 0xc000] << 8) | vid->vram[ca + 0xc001];
|
||||
cursoraddr = ((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000);
|
||||
dat = (vid->vram[cursoraddr] << 8) | vid->vram[cursoraddr + 1];
|
||||
dat2 = (vid->vram[cursoraddr + 0x4000] << 8) | vid->vram[cursoraddr + 0x4001];
|
||||
dat3 = (vid->vram[cursoraddr + 0x8000] << 8) | vid->vram[cursoraddr + 0x8001];
|
||||
dat4 = (vid->vram[cursoraddr + 0xc000] << 8) | vid->vram[cursoraddr + 0xc001];
|
||||
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (vid->cgacol & 15)) + 16;
|
||||
dat <<= 1;
|
||||
@@ -478,7 +479,7 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((vid->cgamode & 0x12) == 0x12) ? 0 : (vid->cgacol & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
} else {
|
||||
@@ -487,7 +488,7 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (vid->cgamode & 1)
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
@@ -495,9 +496,9 @@ vid_poll_1512(void *priv)
|
||||
video_process_8(x, vid->displine << 1);
|
||||
video_process_8(x, (vid->displine << 1) + 1);
|
||||
|
||||
vid->sc = oldsc;
|
||||
vid->scanline = scanline_old;
|
||||
if (vid->vsynctime)
|
||||
vid->stat |= 8;
|
||||
vid->status |= 8;
|
||||
vid->displine++;
|
||||
if (vid->displine >= 360)
|
||||
vid->displine = 0;
|
||||
@@ -506,30 +507,29 @@ 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->sc == (vid->crtc[11] & 31)) {
|
||||
vid->con = 0;
|
||||
vid->coff = 1;
|
||||
if (vid->scanline == (vid->crtc[11] & 31)) {
|
||||
vid->cursorvisible = 0;
|
||||
}
|
||||
if (vid->vadj) {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->scanline++;
|
||||
vid->scanline &= 31;
|
||||
vid->memaddr= vid->memaddr_backup;
|
||||
vid->vadj--;
|
||||
if (!vid->vadj) {
|
||||
vid->dispon = 1;
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->sc = 0;
|
||||
vid->memaddr= vid->memaddr_backup = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->scanline = 0;
|
||||
}
|
||||
} else if (vid->sc == vid->crtc[9]) {
|
||||
vid->maback = vid->ma;
|
||||
vid->sc = 0;
|
||||
} else if (vid->scanline == vid->crtc[9]) {
|
||||
vid->memaddr_backup = vid->memaddr;
|
||||
vid->scanline = 0;
|
||||
vid->vc++;
|
||||
vid->vc &= 127;
|
||||
|
||||
@@ -547,7 +547,7 @@ vid_poll_1512(void *priv)
|
||||
vid->displine = 0;
|
||||
vid->vsynctime = 46;
|
||||
|
||||
if (vid->cgamode & 1)
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
@@ -584,15 +584,15 @@ vid_poll_1512(void *priv)
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->cgamode & 2)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->cgamode & 16)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
@@ -604,12 +604,12 @@ vid_poll_1512(void *priv)
|
||||
vid->blink++;
|
||||
}
|
||||
} else {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->scanline++;
|
||||
vid->scanline &= 31;
|
||||
vid->memaddr= vid->memaddr_backup;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[10] & 31))
|
||||
vid->con = 1;
|
||||
if (vid->scanline == (vid->crtc[10] & 31))
|
||||
vid->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,7 +1046,7 @@ vid_in_200(uint16_t addr, void *priv)
|
||||
|
||||
switch (addr) {
|
||||
case 0x03b8:
|
||||
return (mda->ctrl);
|
||||
return (mda->mode);
|
||||
|
||||
case 0x03d8:
|
||||
return (cga->cgamode);
|
||||
@@ -1108,9 +1108,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;
|
||||
@@ -1212,11 +1212,11 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
static void
|
||||
lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
uint8_t attr, int drawcursor, int blink, int sc,
|
||||
uint8_t attr, int drawcursor, int blink, int scanline,
|
||||
int mode160, uint8_t control)
|
||||
{
|
||||
int c;
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][sc];
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline];
|
||||
uint8_t bright = 0;
|
||||
uint16_t mask;
|
||||
|
||||
@@ -1247,10 +1247,10 @@ lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
|
||||
static void
|
||||
lcd_draw_char_40(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
uint8_t attr, int drawcursor, int blink, int sc,
|
||||
uint8_t attr, int drawcursor, int blink, int scanline,
|
||||
uint8_t control)
|
||||
{
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][sc];
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline];
|
||||
uint8_t mask = 0x80;
|
||||
|
||||
if (attr & 8) /* bright */
|
||||
@@ -1271,92 +1271,91 @@ static void
|
||||
lcdm_poll(amsvid_t *vid)
|
||||
{
|
||||
mda_t *mda = &vid->mda;
|
||||
uint16_t ca = (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;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int blink;
|
||||
|
||||
if (!mda->linepos) {
|
||||
timer_advance_u64(&vid->timer, mda->dispofftime);
|
||||
mda->stat |= 1;
|
||||
mda->status |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
scanline_old = mda->scanline;
|
||||
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++) {
|
||||
chr = mda->vram[(mda->ma << 1) & 0xfff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
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->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl);
|
||||
mda->ma++;
|
||||
lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->scanline, 0, mda->mode);
|
||||
mda->memaddr++;
|
||||
}
|
||||
}
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc)
|
||||
mda->stat |= 8;
|
||||
mda->scanline = scanline_old;
|
||||
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->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
|
||||
mda->con = 0;
|
||||
mda->coff = 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) {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr= mda->memaddr_backup;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj) {
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
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->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) {
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
} 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->ma = mda->maback = (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;
|
||||
@@ -1372,8 +1371,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;
|
||||
@@ -1381,12 +1380,12 @@ lcdm_poll(amsvid_t *vid)
|
||||
mda->blink++;
|
||||
}
|
||||
} else {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr= mda->memaddr_backup;
|
||||
}
|
||||
if (mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))
|
||||
mda->con = 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1402,19 +1401,19 @@ lcdc_poll(amsvid_t *vid)
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int oldsc;
|
||||
uint16_t ca;
|
||||
int scanline_old;
|
||||
uint16_t cursoraddr;
|
||||
int blink;
|
||||
|
||||
ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
cursoraddr = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
if (!cga->linepos) {
|
||||
timer_advance_u64(&vid->timer, cga->dispofftime);
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
scanline_old = cga->scanline;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
cga->scanline = ((cga->scanline << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon) {
|
||||
if (cga->displine < cga->firstline) {
|
||||
cga->firstline = cga->displine;
|
||||
@@ -1422,30 +1421,30 @@ lcdc_poll(amsvid_t *vid)
|
||||
}
|
||||
cga->lastline = cga->displine;
|
||||
|
||||
if (cga->cgamode & 1) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode);
|
||||
cga->ma++;
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode);
|
||||
cga->memaddr++;
|
||||
}
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
chr = cga->vram[(cga->ma << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode);
|
||||
cga->ma++;
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = cga->vram[(cga->memaddr << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->memaddr << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode);
|
||||
cga->memaddr++;
|
||||
}
|
||||
} else { /* Graphics mode */
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
cga->ma++;
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) | cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1];
|
||||
cga->memaddr++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[cga->displine << 1][(x << 4) + c] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c] = (dat & 0x8000) ? blue : green;
|
||||
dat <<= 1;
|
||||
@@ -1453,22 +1452,22 @@ lcdc_poll(amsvid_t *vid)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cga->cgamode & 1) {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 3), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 3), green);
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 3), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 3), green);
|
||||
} else {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 4), green);
|
||||
}
|
||||
}
|
||||
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3);
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3);
|
||||
else
|
||||
x = (cga->crtc[1] << 4);
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4);
|
||||
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->scanline = scanline_old;
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->scanline)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
@@ -1481,54 +1480,53 @@ lcdc_poll(amsvid_t *vid)
|
||||
if (!cga->vsynctime)
|
||||
cga->cgastat &= ~8;
|
||||
}
|
||||
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) {
|
||||
cga->con = 0;
|
||||
cga->coff = 1;
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
cga->cursorvisible = 0;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
if (cga->vadj) {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
cga->scanline = 0;
|
||||
}
|
||||
} else if (cga->sc == cga->crtc[9]) {
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
} else if (cga->scanline == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) {
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
cga->scanline = 0;
|
||||
oldvc = cga->vc;
|
||||
cga->vc++;
|
||||
cga->vc &= 127;
|
||||
|
||||
if (cga->vc == cga->crtc[6])
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VDISP])
|
||||
cga->cgadispon = 0;
|
||||
|
||||
if (oldvc == cga->crtc[4]) {
|
||||
if (oldvc == cga->crtc[CGA_CRTC_VTOTAL]) {
|
||||
cga->vc = 0;
|
||||
cga->vadj = cga->crtc[5];
|
||||
cga->vadj = cga->crtc[CGA_CRTC_VTOTAL_ADJUST];
|
||||
if (!cga->vadj)
|
||||
cga->cgadispon = 1;
|
||||
if (!cga->vadj)
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
if ((cga->crtc[10] & 0x60) == 0x20)
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
if ((cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
cga->cursoron = 0;
|
||||
else
|
||||
cga->cursoron = cga->cgablink & 8;
|
||||
}
|
||||
|
||||
if (cga->vc == cga->crtc[7]) {
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC]) {
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = 16;
|
||||
if (cga->crtc[7]) {
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3);
|
||||
if (cga->crtc[CGA_CRTC_VSYNC]) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3);
|
||||
else
|
||||
x = (cga->crtc[1] << 4);
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4);
|
||||
cga->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
@@ -1540,7 +1538,7 @@ lcdc_poll(amsvid_t *vid)
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
|
||||
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize);
|
||||
@@ -1557,15 +1555,15 @@ lcdc_poll(amsvid_t *vid)
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (cga->cgamode & 1) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
@@ -1577,17 +1575,17 @@ lcdc_poll(amsvid_t *vid)
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
}
|
||||
if (cga->cgadispon)
|
||||
cga->cgastat &= ~1;
|
||||
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1)) {
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff];
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
cga->cursorvisible = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
for (x = 0; x < (cga->crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[((cga->memaddr << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,32 +154,68 @@ machine_at_ps2_ide_init(const machine_t *model)
|
||||
static const device_config_t ibmat_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5170_111585",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "62X082x (11/15/85)", .internal_name = "ibm5170_111585", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47.BIN", "" } },
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{
|
||||
.name = "62X082x (11/15/85)",
|
||||
.internal_name = "ibm5170_111585",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "61X9266 (11/15/85) (Alt)",
|
||||
.internal_name = "ibm5170_111585_alt",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27_61X9266.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47_61X9265.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "648009x (06/10/85)",
|
||||
.internal_name = "ibm5170_061085",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmat/BIOS_5170_10JUN85_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JUN85_U47.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "618102x (01/10/84)",
|
||||
.internal_name = "ibm5170_011084",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmat/BIOS_5170_10JAN84_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JAN84_U47.BIN", "" }
|
||||
},
|
||||
// The following are Diagnostic ROMs.
|
||||
{
|
||||
.name = "Supersoft Diagnostics",
|
||||
.internal_name = "diag_supersoft",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/5170_EVEN_LOW_U27_27256.bin", "roms/machines/diagnostic/5170_ODD_HIGH_U47_27256.bin", "" }
|
||||
},
|
||||
|
||||
{ .name = "61X9266 (11/15/85) (Alt)", .internal_name = "ibm5170_111585_alt", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27_61X9266.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47_61X9265.BIN", "" } },
|
||||
|
||||
{ .name = "648009x (06/10/85)", .internal_name = "ibm5170_061085", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_10JUN85_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JUN85_U47.BIN", "" } },
|
||||
|
||||
{ .name = "618102x (01/10/84)", .internal_name = "ibm5170_011084", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_10JAN84_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JAN84_U47.BIN", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
|
||||
@@ -262,6 +262,19 @@ machine_at_px286_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
machine_at_ctat_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&cs8220_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&keyboard_at_phoenix_device);
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_dells200_init(const machine_t *model)
|
||||
{
|
||||
@@ -274,14 +287,24 @@ machine_at_dells200_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_ctat_common_init(model);
|
||||
|
||||
device_add(&cs8220_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
int
|
||||
machine_at_tuliptc7_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
device_add(&keyboard_at_phoenix_device);
|
||||
ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin",
|
||||
"roms/machines/tuliptc7/tc7bo.bin",
|
||||
0x000f8000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ctat_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1105,7 +1128,7 @@ machine_at_3302_init(const machine_t *model)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(¶dise_pvga1a_ncr3302_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&keyboard_at_ncr_device);
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
|
||||
return ret;
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
@@ -439,7 +439,7 @@ machine_at_d824_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
@@ -457,6 +457,41 @@ machine_at_d824_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_tuliptc38_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/tuliptc38/TULIP1.BIN",
|
||||
0x000f0000, 262144, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&vl82c486_device);
|
||||
device_add(&tulip_jumper_device);
|
||||
|
||||
device_add(&vl82c113_device);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL) {
|
||||
bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN",
|
||||
0x000c0000, 32768, 0);
|
||||
|
||||
device_add(machine_get_vid_device(machine));
|
||||
} else for (uint16_t i = 0; i < 32768; i++)
|
||||
rom[i] = mem_readb_phys(0x000c0000 + i);
|
||||
|
||||
mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000);
|
||||
mem_mapping_set_exec(&bios_mapping, rom);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_martin_init(const machine_t *model)
|
||||
{
|
||||
@@ -2197,18 +2232,66 @@ machine_at_ecs486_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t hot433a_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "hot433a",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "AMI", .internal_name = "hot433a", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } },
|
||||
{ .name = "Award (eSupport update)", .internal_name = "hot433a_award", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t hot433a_device = {
|
||||
.name = "Shuttle HOT-433A",
|
||||
.internal_name = "hot433a_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = hot433a_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_hot433a_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
int is_award = !strcmp(device_get_config_bios("bios"), "hot433a_award");
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
if (is_award)
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
else
|
||||
device_add(&ami_1994_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
@@ -2220,9 +2303,46 @@ machine_at_hot433a_init(const machine_t *model)
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886bf_device);
|
||||
device_add(&um8669f_device);
|
||||
if (is_award)
|
||||
device_add(&um8663af_device);
|
||||
else
|
||||
device_add(&um8669f_device);
|
||||
device_add(&winbond_flash_w29c010_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
if (is_award)
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
else
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
pic_toggle_latch(is_award);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_84xxuuda_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/84xxuuda/uud0520s.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886bf_device);
|
||||
device_add(&um8663bf_device);
|
||||
device_add(&winbond_flash_w29c010_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2327,7 +2447,7 @@ machine_at_actionpc2600_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_tg_ami_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&tgui9440_onboard_pci_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2359,7 +2479,7 @@ machine_at_actiontower8400_init(const machine_t *model)
|
||||
device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too.
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5430_onboard_pci_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
|
||||
static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
enum {
|
||||
COMPAQ_PORTABLEII = 0,
|
||||
COMPAQ_PORTABLEIII,
|
||||
@@ -55,752 +52,11 @@ enum {
|
||||
COMPAQ_DESKPRO386_05_1988
|
||||
};
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
/*Very rough estimate*/
|
||||
#define VID_CLOCK (double) (651 * 416 * 60)
|
||||
|
||||
/* Mapping of attributes to colours */
|
||||
static uint32_t amber;
|
||||
static uint32_t black;
|
||||
static uint32_t blinkcols[256][2];
|
||||
static uint32_t normcols[256][2];
|
||||
|
||||
/* Video options set by the motherboard; they will be picked up by the card
|
||||
* on the next poll.
|
||||
*
|
||||
* Bit 3: Disable built-in video (for add-on card)
|
||||
* Bit 2: Thin font
|
||||
* Bits 0,1: Font set (not currently implemented)
|
||||
*/
|
||||
static int8_t cpq_st_display_internal = -1;
|
||||
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
static void
|
||||
compaq_plasma_display_set(uint8_t internal)
|
||||
{
|
||||
cpq_st_display_internal = internal;
|
||||
}
|
||||
|
||||
typedef struct compaq_plasma_t {
|
||||
cga_t cga;
|
||||
mem_mapping_t font_ram_mapping;
|
||||
uint8_t *font_ram;
|
||||
uint8_t port_13c6;
|
||||
uint8_t port_23c6;
|
||||
uint8_t port_27c6;
|
||||
uint8_t internal_monitor;
|
||||
} compaq_plasma_t;
|
||||
|
||||
static int compaq_machine_type = 0;
|
||||
|
||||
/* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */
|
||||
static mem_mapping_t ram_mapping;
|
||||
|
||||
static void compaq_plasma_recalcattrs(compaq_plasma_t *self);
|
||||
|
||||
static void
|
||||
compaq_plasma_recalctimings(compaq_plasma_t *self)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
cga_recalctimings(&self->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_waitstates(UNUSED(void *priv))
|
||||
{
|
||||
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
self->font_ram[addr & 0x1fff] = val;
|
||||
else
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
}
|
||||
static uint8_t
|
||||
compaq_plasma_read(uint32_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
ret = (self->font_ram[addr & 0x1fff]);
|
||||
else
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
/* Emulated CRTC, register select */
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
/* Emulated CRTC, value */
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
cga_out(addr, val, &self->cga);
|
||||
compaq_plasma_recalctimings(self);
|
||||
break;
|
||||
case 0x3d8:
|
||||
case 0x3d9:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
self->port_13c6 = val;
|
||||
compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0);
|
||||
/*
|
||||
For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA;
|
||||
Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA;
|
||||
This leads me to believe bit 2 is not relevant to the mode.
|
||||
*/
|
||||
if ((val & 0x03) == 0x03)
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000);
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
self->port_23c6 = val;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
self->port_27c6 = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_in(uint16_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d4:
|
||||
case 0x3da:
|
||||
case 0x3db:
|
||||
case 0x3dc:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d8:
|
||||
ret = self->cga.cgamode;
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
ret = self->port_13c6;
|
||||
#if 0
|
||||
if ((self->cga.cgamode & 0x28) == 0x00)
|
||||
ret |= 0x04;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x17c6:
|
||||
ret = 0xe6;
|
||||
break;
|
||||
|
||||
case 0x1bc6:
|
||||
ret = 0x40;
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
ret = self->port_23c6;
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
ret = self->port_27c6 & 0x3f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_poll(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
|
||||
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff;
|
||||
uint16_t addr;
|
||||
int drawcursor;
|
||||
int cursorline;
|
||||
int blink = 0;
|
||||
int underline = 0;
|
||||
int c;
|
||||
int x;
|
||||
uint32_t ink = 0;
|
||||
uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black;
|
||||
uint32_t bg = black;
|
||||
uint32_t cols[2];
|
||||
uint8_t dat;
|
||||
uint8_t pattern;
|
||||
uint32_t ink0 = 0;
|
||||
uint32_t ink1 = 0;
|
||||
|
||||
/* Switch between internal plasma and external CRT display. */
|
||||
if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) {
|
||||
self->internal_monitor = cpq_st_display_internal;
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
/* graphic mode and not mode 40h */
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
} else {
|
||||
/* mode 40h or text mode */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine == 0)
|
||||
video_wait_for_buffer();
|
||||
|
||||
/* 80-col */
|
||||
if (self->cga.cgamode & 0x01) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) << 1;
|
||||
ma += (self->cga.displine >> 4) * 80;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
/* for each text column */
|
||||
for (x = 0; x < 80; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] ^= (amber ^ black);
|
||||
} else if ((self->port_23c6 >> 5) == 4) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(self->cga.cgamode & 0x02)) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) << 1;
|
||||
ma += (self->cga.displine >> 4) * 40;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
for (x = 0; x < 40; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1)
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] ^= (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] ^= (amber ^ black);
|
||||
}
|
||||
else if ((self->port_23c6 >> 5) == 4)
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
} else {
|
||||
if (self->cga.cgamode & 0x10) {
|
||||
/* 640x400 mode */
|
||||
if (self->port_23c6 & 0x01) /* 640*400 */ {
|
||||
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
ink = black;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = ink;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
case 0:
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = amber;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ink0 = ink1 = amber;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1)] = ink0;
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1) + 1] = ink1;
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self->cga.displine++;
|
||||
/* Hardcode a fixed refresh rate and VSYNC timing */
|
||||
if (self->cga.displine == 400) { /* Start of VSYNC */
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.cgadispon = 0;
|
||||
}
|
||||
if (self->cga.displine == 416) { /* End of VSYNC */
|
||||
self->cga.displine = 0;
|
||||
self->cga.cgastat &= ~8;
|
||||
self->cga.cgadispon = 1;
|
||||
}
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
self->cga.linepos = 0;
|
||||
|
||||
if (self->cga.displine == 400) {
|
||||
xsize = 640;
|
||||
ysize = 400;
|
||||
|
||||
if ((self->cga.cgamode & 0x08) || video_force_resize_get()) {
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
/* Plasma specific */
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* Fixed 640x400 resolution */
|
||||
video_res_x = 640;
|
||||
video_res_y = 400;
|
||||
|
||||
if (self->cga.cgamode & 0x02) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 0;
|
||||
|
||||
self->cga.cgablink++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_mdaattr_rebuild(void)
|
||||
{
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* val behaves as follows:
|
||||
* Bit 0: Attributes 01-06, 08-0E are inverse video
|
||||
* Bit 1: Attributes 01-06, 08-0E are bold
|
||||
* Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are inverse video
|
||||
* Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are bold */
|
||||
|
||||
/* Set up colours */
|
||||
amber = makecol(0xff, 0x7d, 0x00);
|
||||
black = makecol(0x64, 0x19, 0x00);
|
||||
|
||||
/* Initialize the attribute mapping. Start by defaulting everything
|
||||
* to black on amber, and with bold set by bit 3 */
|
||||
for (n = 0; n < 256; n++) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
}
|
||||
|
||||
/* Colours 0x11-0xFF are controlled by bits 2 and 3 of the
|
||||
* passed value. Exclude x0 and x8, which are always black on
|
||||
* amber. */
|
||||
for (n = 0x11; n <= 0xFF; n++) {
|
||||
if ((n & 7) == 0)
|
||||
continue;
|
||||
if ((self->port_23c6 >> 5) == 1) { /* Inverse */
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
} else { /* Normal */
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
}
|
||||
}
|
||||
/* Set up the 01-0E range, controlled by bits 0 and 1 of the
|
||||
* passed value. When blinking is enabled this also affects 81-8E. */
|
||||
for (n = 0x01; n <= 0x0E; n++) {
|
||||
if (n == 7)
|
||||
continue;
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = amber;
|
||||
blinkcols[n + 128][1] = black;
|
||||
} else {
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
}
|
||||
/* Colours 07 and 0F are always amber on black. If blinking is
|
||||
* enabled so are 87 and 8F. */
|
||||
for (n = 0x07; n <= 0x0F; n += 8) {
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
/* When not blinking, colours 81-8F are always amber on black. */
|
||||
for (n = 0x81; n <= 0x8F; n++) {
|
||||
normcols[n][0] = black;
|
||||
normcols[n][1] = amber;
|
||||
}
|
||||
|
||||
/* Finally do the ones which are solid black. These differ between
|
||||
* the normal and blinking mappings */
|
||||
for (n = 0; n <= 0xFF; n += 0x11)
|
||||
normcols[n][0] = normcols[n][1] = black;
|
||||
|
||||
/* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */
|
||||
for (n = 0; n <= 0x77; n += 0x11) {
|
||||
blinkcols[n][0] = blinkcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = blinkcols[n + 128][1] = black;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_plasma_init(UNUSED(const device_t *info))
|
||||
{
|
||||
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
|
||||
|
||||
cga_init(&self->cga);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
|
||||
|
||||
self->cga.composite = 0;
|
||||
self->cga.revision = 0;
|
||||
|
||||
self->cga.vram = malloc(0x8000);
|
||||
self->internal_monitor = 1;
|
||||
self->font_ram = malloc(0x2000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_set_callback(&self->cga.timer, compaq_plasma_poll);
|
||||
timer_set_p(&self->cga.timer, self);
|
||||
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000,
|
||||
compaq_plasma_read, NULL, NULL,
|
||||
compaq_plasma_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
}
|
||||
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
compaq_plasma_mdaattr_rebuild();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_close(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self->font_ram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_speed_changed(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
const device_config_t compaq_plasma_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "RGB type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Color", .value = 0 },
|
||||
{ .description = "Green Monochrome", .value = 1 },
|
||||
{ .description = "Amber Monochrome", .value = 2 },
|
||||
{ .description = "Gray Monochrome", .value = 3 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t compaq_plasma_device = {
|
||||
.name = "Compaq Plasma",
|
||||
.internal_name = "compaq_plasma",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_plasma_init,
|
||||
.close = compaq_plasma_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_plasma_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = compaq_plasma_config
|
||||
};
|
||||
|
||||
static uint8_t
|
||||
read_ram(uint32_t addr, UNUSED(void *priv))
|
||||
|
||||
@@ -58,13 +58,13 @@ static void
|
||||
elt_vid_off_poll(void *priv)
|
||||
{
|
||||
cga_t *cga = priv;
|
||||
uint8_t hdisp = cga->crtc[1];
|
||||
uint8_t hdisp = cga->crtc[CGA_CRTC_HDISP];
|
||||
|
||||
/* Don't display anything.
|
||||
* TODO: Do something less stupid to emulate backlight off. */
|
||||
cga->crtc[1] = 0;
|
||||
cga->crtc[CGA_CRTC_HDISP] = 0;
|
||||
cga_poll(cga);
|
||||
cga->crtc[1] = hdisp;
|
||||
cga->crtc[CGA_CRTC_HDISP] = hdisp;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -646,6 +646,7 @@ europc_boot(UNUSED(const device_t *info))
|
||||
* (JS9) can be used to "move" it to 0x0350, to get it out of
|
||||
* the way of other cards that need this range.
|
||||
*/
|
||||
sys->jim = device_get_config_hex16("js9");
|
||||
io_sethandler(sys->jim, 16,
|
||||
jim_read, NULL, NULL, jim_write, NULL, NULL, sys);
|
||||
|
||||
@@ -680,14 +681,14 @@ static const device_config_t europc_config[] = {
|
||||
{
|
||||
.name = "js9",
|
||||
.description = "JS9 Jumper (JIM)",
|
||||
.type = CONFIG_INT,
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.default_int = 0x0250,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled (250h)", .value = 0 },
|
||||
{ .description = "Enabled (350h)", .value = 1 },
|
||||
{ .description = "Disabled (250h)", .value = 0x0250 },
|
||||
{ .description = "Enabled (350h)", .value = 0x0350 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
|
||||
@@ -48,11 +48,10 @@
|
||||
#include <86box/snd_sn76489.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/m_pcjr.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
|
||||
#define STAT_PARITY 0x80
|
||||
#define STAT_RTIMEOUT 0x40
|
||||
@@ -63,50 +62,10 @@
|
||||
#define STAT_IFULL 0x02
|
||||
#define STAT_OFULL 0x01
|
||||
|
||||
typedef struct pcjr_t {
|
||||
/* Video Controller stuff. */
|
||||
mem_mapping_t mapping;
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
int array_index;
|
||||
uint8_t array[32];
|
||||
int array_ff;
|
||||
int memctrl;
|
||||
uint8_t stat;
|
||||
int addr_mode;
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int vc;
|
||||
int dispon;
|
||||
int con;
|
||||
int coff;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
int composite;
|
||||
int apply_hd;
|
||||
|
||||
/* Keyboard Controller stuff. */
|
||||
int latched;
|
||||
int data;
|
||||
int serial_data[44];
|
||||
int serial_pos;
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
pc_timer_t send_delay_timer;
|
||||
} pcjr_t;
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0;
|
||||
static int key_queue_end = 0;
|
||||
|
||||
/*PCjr keyboard has no escape scancodes, and no scancodes beyond 54
|
||||
Map right alt to 54h (FN) */
|
||||
@@ -627,644 +586,6 @@ const scancode scancode_pcjr[512] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/
|
||||
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0;
|
||||
static int key_queue_end = 0;
|
||||
|
||||
static void
|
||||
recalc_address(pcjr_t *pcjr)
|
||||
{
|
||||
uint8_t masked_memctrl = pcjr->memctrl;
|
||||
|
||||
/* According to the Technical Reference, bits 2 and 5 are
|
||||
ignored if there is only 64k of RAM and there are only
|
||||
4 pages. */
|
||||
if (mem_size < 128)
|
||||
masked_memctrl &= ~0x24;
|
||||
|
||||
if ((pcjr->memctrl & 0xc0) == 0xc0) {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x06) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11];
|
||||
} else {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x07) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_timings(pcjr_t *pcjr)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
disptime = pcjr->crtc[0] + 1;
|
||||
_dispontime = pcjr->crtc[1];
|
||||
} else {
|
||||
disptime = (pcjr->crtc[0] + 1) << 1;
|
||||
_dispontime = pcjr->crtc[1] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
pcjr->dispontime = (uint64_t) (_dispontime);
|
||||
pcjr->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_size(pcjr_t *pcjr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
ret = 128;
|
||||
else
|
||||
ret = 256;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
pcjr->crtcreg = val & 0x1f;
|
||||
return;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
old = pcjr->crtc[pcjr->crtcreg];
|
||||
pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg];
|
||||
if (pcjr->crtcreg == 2)
|
||||
overscan_x = vid_get_h_overscan_size(pcjr);
|
||||
if (old != val) {
|
||||
if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) {
|
||||
pcjr->fullchange = changeframecount;
|
||||
recalc_timings(pcjr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3da:
|
||||
if (!pcjr->array_ff)
|
||||
pcjr->array_index = val & 0x1f;
|
||||
else {
|
||||
if (pcjr->array_index & 0x10)
|
||||
val &= 0x0f;
|
||||
pcjr->array[pcjr->array_index & 0x1f] = val;
|
||||
if (!(pcjr->array_index & 0x1f))
|
||||
update_cga16_color(val);
|
||||
}
|
||||
pcjr->array_ff = !pcjr->array_ff;
|
||||
break;
|
||||
|
||||
case 0x3df:
|
||||
pcjr->memctrl = val;
|
||||
pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to
|
||||
then be readable from port 60, others it errors out
|
||||
with only 64k RAM set (but somehow, still works with
|
||||
128k or more RAM). */
|
||||
pcjr->addr_mode = val >> 6;
|
||||
recalc_address(pcjr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
ret = pcjr->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = pcjr->crtc[pcjr->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x3da:
|
||||
pcjr->array_ff = 0;
|
||||
pcjr->stat ^= 0x10;
|
||||
ret = pcjr->stat;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return;
|
||||
|
||||
pcjr->b8000[addr & 0x3fff] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_read(uint32_t addr, void *priv)
|
||||
{
|
||||
const pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return 0xff;
|
||||
|
||||
return (pcjr->b8000[addr & 0x3fff]);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_delta(pcjr_t *pcjr)
|
||||
{
|
||||
int def;
|
||||
int coef;
|
||||
int ret;
|
||||
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
def = 0x2c; /* I'm going to assume a datasheet erratum here. */
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
def = 0x5a;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
default:
|
||||
def = 0x2c;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = pcjr->crtc[0x02] - def;
|
||||
|
||||
if (ret < -8)
|
||||
ret = -8;
|
||||
|
||||
if (ret > 8)
|
||||
ret = 8;
|
||||
|
||||
return ret * coef;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_blit_h_overscan(pcjr_t *pcjr)
|
||||
{
|
||||
int cols = (pcjr->array[2] & 0xf) + 16;;
|
||||
int y0 = pcjr->firstline << 1;
|
||||
int y = (pcjr->lastline << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int i;
|
||||
int x;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
hline(buffer32, 0, y0 + i, x, cols);
|
||||
hline(buffer32, 0, y + i, x, cols);
|
||||
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y0 + i]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y + i]);
|
||||
} else {
|
||||
video_process_8(x, y0 + i);
|
||||
video_process_8(x, y + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_poll(void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int oldsc;
|
||||
int l = (pcjr->displine << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int ho_d = vid_get_h_overscan_delta(pcjr) + (ho_s / 2);
|
||||
|
||||
if (!pcjr->linepos) {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispofftime);
|
||||
pcjr->stat &= ~1;
|
||||
pcjr->linepos = 1;
|
||||
oldsc = pcjr->sc;
|
||||
if ((pcjr->crtc[8] & 3) == 3)
|
||||
pcjr->sc = (pcjr->sc << 1) & 7;
|
||||
if (pcjr->dispon) {
|
||||
uint16_t offset = 0;
|
||||
uint16_t mask = 0x1fff;
|
||||
|
||||
if (pcjr->displine < pcjr->firstline) {
|
||||
pcjr->firstline = pcjr->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
pcjr->lastline = pcjr->displine;
|
||||
cols[0] = (pcjr->array[2] & 0xf) + 16;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
|
||||
switch (pcjr->addr_mode) {
|
||||
case 0: /*Alpha*/
|
||||
offset = 0;
|
||||
mask = 0x3fff;
|
||||
break;
|
||||
case 1: /*Low resolution graphics*/
|
||||
offset = (pcjr->sc & 1) * 0x2000;
|
||||
break;
|
||||
case 3: /*High resolution graphics*/
|
||||
offset = (pcjr->sc & 3) * 0x2000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] =
|
||||
buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] =
|
||||
buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] =
|
||||
buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] =
|
||||
buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] =
|
||||
buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] =
|
||||
buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
chr = (dat >> 7) & 1;
|
||||
chr |= ((dat >> 14) & 2);
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
if (pcjr->sc & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] =
|
||||
cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
pcjr->ma++;
|
||||
}
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
pcjr->ma++;
|
||||
if (pcjr->sc & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] =
|
||||
cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
cols[2] = pcjr->array[2 + 16] + 16;
|
||||
cols[3] = pcjr->array[3 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pcjr->array[3] & 4) {
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
}
|
||||
} else {
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l + 1]);
|
||||
} else {
|
||||
video_process_8(x, l);
|
||||
video_process_8(x, l + 1);
|
||||
}
|
||||
pcjr->sc = oldsc;
|
||||
if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) {
|
||||
pcjr->stat |= 8;
|
||||
}
|
||||
pcjr->displine++;
|
||||
if (pcjr->displine >= 360)
|
||||
pcjr->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispontime);
|
||||
if (pcjr->dispon)
|
||||
pcjr->stat |= 1;
|
||||
pcjr->linepos = 0;
|
||||
if (pcjr->vsynctime) {
|
||||
pcjr->vsynctime--;
|
||||
if (!pcjr->vsynctime) {
|
||||
pcjr->stat &= ~8;
|
||||
}
|
||||
}
|
||||
if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) {
|
||||
pcjr->con = 0;
|
||||
pcjr->coff = 1;
|
||||
}
|
||||
if (pcjr->vadj) {
|
||||
pcjr->sc++;
|
||||
pcjr->sc &= 31;
|
||||
pcjr->ma = pcjr->maback;
|
||||
pcjr->vadj--;
|
||||
if (!pcjr->vadj) {
|
||||
pcjr->dispon = 1;
|
||||
pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
pcjr->sc = 0;
|
||||
}
|
||||
} else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) {
|
||||
pcjr->maback = pcjr->ma;
|
||||
pcjr->sc = 0;
|
||||
oldvc = pcjr->vc;
|
||||
pcjr->vc++;
|
||||
pcjr->vc &= 127;
|
||||
if (pcjr->vc == pcjr->crtc[6])
|
||||
pcjr->dispon = 0;
|
||||
if (oldvc == pcjr->crtc[4]) {
|
||||
pcjr->vc = 0;
|
||||
pcjr->vadj = pcjr->crtc[5];
|
||||
if (!pcjr->vadj)
|
||||
pcjr->dispon = 1;
|
||||
if (!pcjr->vadj)
|
||||
pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
if ((pcjr->crtc[10] & 0x60) == 0x20)
|
||||
pcjr->cursoron = 0;
|
||||
else
|
||||
pcjr->cursoron = pcjr->blink & 16;
|
||||
}
|
||||
if (pcjr->vc == pcjr->crtc[7]) {
|
||||
pcjr->dispon = 0;
|
||||
pcjr->displine = 0;
|
||||
pcjr->vsynctime = 16;
|
||||
picint(1 << 5);
|
||||
if (pcjr->crtc[7]) {
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
pcjr->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (pcjr->lastline - pcjr->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
int actual_ys = ys_temp;
|
||||
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= ho_s;
|
||||
|
||||
if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
vid_blit_h_overscan(pcjr);
|
||||
|
||||
if (enable_overscan) {
|
||||
video_blit_memtoscreen(0, pcjr->firstline << 1,
|
||||
xsize, actual_ys + 32);
|
||||
} else if (pcjr->apply_hd) {
|
||||
video_blit_memtoscreen(ho_s / 2, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
} else {
|
||||
video_blit_memtoscreen(ho_d, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
}
|
||||
pcjr->firstline = 1000;
|
||||
pcjr->lastline = 0;
|
||||
pcjr->blink++;
|
||||
}
|
||||
} else {
|
||||
pcjr->sc++;
|
||||
pcjr->sc &= 31;
|
||||
pcjr->ma = pcjr->maback;
|
||||
}
|
||||
if (pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1)))
|
||||
pcjr->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
@@ -1435,35 +756,7 @@ speed_changed(void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
recalc_timings(pcjr);
|
||||
}
|
||||
|
||||
static void
|
||||
pcjr_vid_init(pcjr_t *pcjr)
|
||||
{
|
||||
int display_type;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
|
||||
|
||||
pcjr->memctrl = -1;
|
||||
if (mem_size < 128)
|
||||
pcjr->memctrl &= ~0x24;
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
pcjr->composite = (display_type != PCJR_RGB);
|
||||
pcjr->apply_hd = device_get_config_int("apply_hd");
|
||||
overscan_x = 256;
|
||||
overscan_y = 32;
|
||||
|
||||
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
|
||||
vid_read, NULL, NULL,
|
||||
vid_write, NULL, NULL, NULL, 0, pcjr);
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr);
|
||||
timer_add(&pcjr->timer, vid_poll, pcjr, 1);
|
||||
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
pcjr_recalc_timings(pcjr);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -44,12 +44,9 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_tandy.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
enum {
|
||||
TANDY_RGB = 0,
|
||||
TANDY_COMPOSITE
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_TANDY = 0,
|
||||
@@ -65,80 +62,6 @@ enum {
|
||||
EEPROM_WRITE
|
||||
};
|
||||
|
||||
typedef struct t1kvid_t {
|
||||
mem_mapping_t mapping;
|
||||
mem_mapping_t vram_mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
int array_index;
|
||||
uint8_t array[256];
|
||||
int memctrl;
|
||||
uint8_t mode;
|
||||
uint8_t col;
|
||||
uint8_t stat;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
uint32_t b8000_mask;
|
||||
uint32_t b8000_limit;
|
||||
uint8_t planar_ctrl;
|
||||
uint8_t lp_strobe;
|
||||
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int vc;
|
||||
int dispon;
|
||||
int con;
|
||||
int coff;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int fullchange;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
|
||||
int composite;
|
||||
} t1kvid_t;
|
||||
|
||||
typedef struct t1keep_t {
|
||||
char *path;
|
||||
|
||||
int state;
|
||||
int count;
|
||||
int addr;
|
||||
int clk;
|
||||
uint16_t data;
|
||||
uint16_t store[64];
|
||||
} t1keep_t;
|
||||
|
||||
typedef struct tandy_t {
|
||||
mem_mapping_t ram_mapping;
|
||||
mem_mapping_t rom_mapping; /* SL2 */
|
||||
|
||||
uint8_t *rom; /* SL2 */
|
||||
uint8_t ram_bank;
|
||||
uint8_t rom_bank; /* SL2 */
|
||||
int rom_offset; /* SL2 */
|
||||
|
||||
uint32_t base;
|
||||
uint32_t mask;
|
||||
int is_hx;
|
||||
int is_sl2;
|
||||
|
||||
t1kvid_t *vid;
|
||||
} tandy_t;
|
||||
|
||||
static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/
|
||||
|
||||
static const scancode scancode_tandy[512] = {
|
||||
// clang-format off
|
||||
@@ -656,22 +579,8 @@ static const scancode scancode_tandy[512] = {
|
||||
{ .mk = { 0 }, .brk = { 0 } } /* 1ff */
|
||||
// clang-format on
|
||||
};
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t crtcmask_sl[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static int eep_data_out;
|
||||
|
||||
static uint8_t vid_in(uint16_t addr, void *priv);
|
||||
static void vid_out(uint16_t addr, uint8_t val, void *priv);
|
||||
static int eep_data_out;
|
||||
|
||||
#ifdef ENABLE_TANDY_LOG
|
||||
int tandy_do_log = ENABLE_TANDY_LOG;
|
||||
@@ -691,763 +600,7 @@ tandy_log(const char *fmt, ...)
|
||||
# define tandy_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
recalc_mapping(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
mem_mapping_disable(&vid->mapping);
|
||||
io_removehandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
|
||||
if (vid->planar_ctrl & 4) {
|
||||
mem_mapping_enable(&vid->mapping);
|
||||
if (vid->array[5] & 1)
|
||||
mem_mapping_set_addr(&vid->mapping, 0xa0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&vid->mapping, 0xb8000, 0x8000);
|
||||
io_sethandler(0x03d0, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_timings(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (vid->mode & 1) {
|
||||
disptime = vid->crtc[0] + 1;
|
||||
_dispontime = vid->crtc[1];
|
||||
} else {
|
||||
disptime = (vid->crtc[0] + 1) << 1;
|
||||
_dispontime = vid->crtc[1] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
vid->dispontime = (uint64_t) (_dispontime);
|
||||
vid->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_address(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
if ((vid->memctrl & 0xc0) == 0xc0) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base];
|
||||
vid->b8000_mask = 0x7fff;
|
||||
} else {
|
||||
vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base];
|
||||
vid->b8000_mask = 0x3fff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_address_sl(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
vid->b8000_limit = 0x8000;
|
||||
|
||||
if (vid->array[5] & 1) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x04) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x20) << 11) + dev->base];
|
||||
} else if ((vid->memctrl & 0xc0) == 0xc0) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base];
|
||||
} else {
|
||||
vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base];
|
||||
if ((vid->memctrl & 0x38) == 0x38)
|
||||
vid->b8000_limit = 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_update_latch(t1kvid_t *vid)
|
||||
{
|
||||
uint32_t lp_latch = vid->displine * vid->crtc[1];
|
||||
|
||||
vid->crtc[0x10] = (lp_latch >> 8) & 0x3f;
|
||||
vid->crtc[0x11] = lp_latch & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint8_t old;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x03d4:
|
||||
vid->crtcreg = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x03d5:
|
||||
old = vid->crtc[vid->crtcreg];
|
||||
if (dev->is_sl2)
|
||||
vid->crtc[vid->crtcreg] = val & crtcmask_sl[vid->crtcreg];
|
||||
else
|
||||
vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg];
|
||||
if (old != val) {
|
||||
if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) {
|
||||
vid->fullchange = changeframecount;
|
||||
recalc_timings(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03d8:
|
||||
old = vid->mode;
|
||||
vid->mode = val;
|
||||
if ((old ^ val) & 0x01)
|
||||
recalc_timings(dev);
|
||||
if (!dev->is_sl2)
|
||||
update_cga16_color(vid->mode);
|
||||
break;
|
||||
|
||||
case 0x03d9:
|
||||
vid->col = val;
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
vid->array_index = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x3db:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 1))
|
||||
vid->lp_strobe = 0;
|
||||
break;
|
||||
|
||||
case 0x3dc:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||
vid->lp_strobe = 1;
|
||||
vid_update_latch(vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03de:
|
||||
if (vid->array_index & 16)
|
||||
val &= 0xf;
|
||||
vid->array[vid->array_index & 0x1f] = val;
|
||||
if (dev->is_sl2) {
|
||||
if ((vid->array_index & 0x1f) == 5) {
|
||||
recalc_mapping(dev);
|
||||
recalc_address_sl(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03df:
|
||||
vid->memctrl = val;
|
||||
if (dev->is_sl2)
|
||||
recalc_address_sl(dev);
|
||||
else
|
||||
recalc_address(dev);
|
||||
break;
|
||||
|
||||
case 0x0065:
|
||||
if (val == 8)
|
||||
return; /*Hack*/
|
||||
vid->planar_ctrl = val;
|
||||
recalc_mapping(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
const tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x03d4:
|
||||
ret = vid->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x03d5:
|
||||
ret = vid->crtc[vid->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
ret = vid->stat;
|
||||
break;
|
||||
|
||||
case 0x3db:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 1))
|
||||
vid->lp_strobe = 0;
|
||||
break;
|
||||
|
||||
case 0x3dc:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||
vid->lp_strobe = 1;
|
||||
vid_update_latch(vid);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
if (vid->memctrl == -1)
|
||||
return;
|
||||
|
||||
if (dev->is_sl2) {
|
||||
if (vid->array[5] & 1)
|
||||
vid->b8000[addr & 0xffff] = val;
|
||||
else {
|
||||
if ((addr & 0x7fff) < vid->b8000_limit)
|
||||
vid->b8000[addr & 0x7fff] = val;
|
||||
}
|
||||
} else {
|
||||
vid->b8000[addr & vid->b8000_mask] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_read(uint32_t addr, void *priv)
|
||||
{
|
||||
const tandy_t *dev = (tandy_t *) priv;
|
||||
const t1kvid_t *vid = dev->vid;
|
||||
|
||||
if (vid->memctrl == -1)
|
||||
return 0xff;
|
||||
|
||||
if (dev->is_sl2) {
|
||||
if (vid->array[5] & 1)
|
||||
return (vid->b8000[addr & 0xffff]);
|
||||
if ((addr & 0x7fff) < vid->b8000_limit)
|
||||
return (vid->b8000[addr & 0x7fff]);
|
||||
else
|
||||
return 0xff;
|
||||
} else {
|
||||
return (vid->b8000[addr & vid->b8000_mask]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_poll(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
||||
if (!vid->linepos) {
|
||||
timer_advance_u64(&vid->timer, vid->dispofftime);
|
||||
vid->stat |= 1;
|
||||
vid->linepos = 1;
|
||||
oldsc = vid->sc;
|
||||
if ((vid->crtc[8] & 3) == 3)
|
||||
vid->sc = (vid->sc << 1) & 7;
|
||||
if (vid->dispon) {
|
||||
if (vid->displine < vid->firstline) {
|
||||
vid->firstline = vid->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
vid->lastline = vid->displine;
|
||||
cols[0] = (vid->array[2] & 0xf) + 16;
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->array[3] & 4) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = cols[0];
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = cols[0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = cols[0];
|
||||
}
|
||||
} else if ((vid->mode & 0x12) == 0x12) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = 0;
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->col & 15) + 16;
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/
|
||||
for (x = 0; x < vid->crtc[1] * 2; x++) {
|
||||
dat = (vid->vram[(vid->ma << 1) & 0xffff] << 8) | vid->vram[((vid->ma << 1) + 1) & 0xffff];
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16;
|
||||
}
|
||||
} else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8] = buffer32->line[vid->displine << 1][(x << 3) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 10] = buffer32->line[vid->displine << 1][(x << 3) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 12] = buffer32->line[vid->displine << 1][(x << 3) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 14] = buffer32->line[vid->displine << 1][(x << 3) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 15] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
} else if (vid->array[3] & 0x10) { /*160x200x16*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
if (dev->is_sl2) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
} else {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
}
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 8] = buffer32->line[vid->displine << 1][(x << 4) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 9] = buffer32->line[vid->displine << 1][(x << 4) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 10] = buffer32->line[vid->displine << 1][(x << 4) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 12] = buffer32->line[vid->displine << 1][(x << 4) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 13] = buffer32->line[vid->displine << 1][(x << 4) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 14] = buffer32->line[vid->displine << 1][(x << 4) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 16] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 16] = buffer32->line[vid->displine << 1][(x << 4) + 17] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 17] = buffer32->line[vid->displine << 1][(x << 4) + 18] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 18] = buffer32->line[vid->displine << 1][(x << 4) + 19] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 20] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 20] = buffer32->line[vid->displine << 1][(x << 4) + 21] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 21] = buffer32->line[vid->displine << 1][(x << 4) + 22] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 22] = buffer32->line[vid->displine << 1][(x << 4) + 23] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 23] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
chr = (dat >> 6) & 2;
|
||||
chr |= ((dat >> 15) & 1);
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 8 + c] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
} else if (vid->mode & 1) {
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->mode & 0x20) {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
|
||||
}
|
||||
if (vid->sc & 8) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[0];
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->sc == 8) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] ^= 15;
|
||||
buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] ^= 15;
|
||||
}
|
||||
}
|
||||
vid->ma++;
|
||||
}
|
||||
} else if (!(vid->mode & 2)) {
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->mode & 0x20) {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
|
||||
}
|
||||
vid->ma++;
|
||||
if (vid->sc & 8) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = cols[0];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->sc == 8) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] ^= 15;
|
||||
buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] ^= 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(vid->mode & 16)) {
|
||||
cols[0] = (vid->col & 15);
|
||||
col = (vid->col & 16) ? 8 : 0;
|
||||
if (vid->mode & 4) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
} else if (vid->col & 32) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
} else {
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
cols[0] = vid->array[(cols[0] & vid->array[1]) + 16] + 16;
|
||||
cols[1] = vid->array[(cols[1] & vid->array[1]) + 16] + 16;
|
||||
cols[2] = vid->array[(cols[2] & vid->array[1]) + 16] + 16;
|
||||
cols[3] = vid->array[(cols[3] & vid->array[1]) + 16] + 16;
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = 0;
|
||||
cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16;
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (vid->array[3] & 4) {
|
||||
if (vid->mode & 1) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
|
||||
} else {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16;
|
||||
if (vid->mode & 1) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vid->mode & 1)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
if (!dev->is_sl2 && vid->composite) {
|
||||
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine << 1]);
|
||||
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1) + 1]);
|
||||
} else {
|
||||
video_process_8(x, vid->displine << 1);
|
||||
video_process_8(x, (vid->displine << 1) + 1);
|
||||
}
|
||||
vid->sc = oldsc;
|
||||
if (vid->vc == vid->crtc[7] && !vid->sc)
|
||||
vid->stat |= 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->linepos = 0;
|
||||
if (vid->vsynctime) {
|
||||
vid->vsynctime--;
|
||||
if (!vid->vsynctime)
|
||||
vid->stat &= ~8;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) {
|
||||
vid->con = 0;
|
||||
vid->coff = 1;
|
||||
}
|
||||
if (vid->vadj) {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->vadj--;
|
||||
if (!vid->vadj) {
|
||||
vid->dispon = 1;
|
||||
if (dev->is_sl2 && (vid->array[5] & 1))
|
||||
vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8);
|
||||
else
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->sc = 0;
|
||||
}
|
||||
} else if (vid->sc == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->sc == (vid->crtc[9] >> 1))) {
|
||||
vid->maback = vid->ma;
|
||||
vid->sc = 0;
|
||||
oldvc = vid->vc;
|
||||
vid->vc++;
|
||||
if (dev->is_sl2)
|
||||
vid->vc &= 255;
|
||||
else
|
||||
vid->vc &= 127;
|
||||
if (vid->vc == vid->crtc[6])
|
||||
vid->dispon = 0;
|
||||
if (oldvc == vid->crtc[4]) {
|
||||
vid->vc = 0;
|
||||
vid->vadj = vid->crtc[5];
|
||||
if (!vid->vadj)
|
||||
vid->dispon = 1;
|
||||
if (!vid->vadj) {
|
||||
if (dev->is_sl2 && (vid->array[5] & 1))
|
||||
vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8);
|
||||
else
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
if ((vid->crtc[10] & 0x60) == 0x20)
|
||||
vid->cursoron = 0;
|
||||
else
|
||||
vid->cursoron = vid->blink & 16;
|
||||
}
|
||||
if (vid->vc == vid->crtc[7]) {
|
||||
vid->dispon = 0;
|
||||
vid->displine = 0;
|
||||
vid->vsynctime = 16;
|
||||
picint(1 << 5);
|
||||
if (vid->crtc[7]) {
|
||||
if (vid->mode & 1)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
vid->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (vid->lastline - vid->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan) {
|
||||
video_blit_memtoscreen(0, (vid->firstline - 4) << 1,
|
||||
xsize, ((vid->lastline - vid->firstline) + 8) << 1);
|
||||
} else {
|
||||
video_blit_memtoscreen(8, vid->firstline << 1,
|
||||
xsize, (vid->lastline - vid->firstline) << 1);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
|
||||
video_res_x /= 2;
|
||||
video_bpp = 4;
|
||||
} else if (vid->array[3] & 0x10) { /*160x200x16*/
|
||||
video_res_x /= 4;
|
||||
video_bpp = 4;
|
||||
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
|
||||
video_bpp = 2;
|
||||
} else if (vid->mode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->mode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->mode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
vid->firstline = 1000;
|
||||
vid->lastline = 0;
|
||||
vid->blink++;
|
||||
}
|
||||
} else {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1)))
|
||||
vid->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_speed_changed(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
|
||||
recalc_timings(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
vid_close(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
|
||||
free(dev->vid);
|
||||
dev->vid = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_init(tandy_t *dev)
|
||||
{
|
||||
int display_type;
|
||||
t1kvid_t *vid;
|
||||
|
||||
vid = calloc(1, sizeof(t1kvid_t));
|
||||
vid->memctrl = -1;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
vid->composite = (display_type != TANDY_RGB);
|
||||
|
||||
cga_comp_init(1);
|
||||
|
||||
if (dev->is_sl2) {
|
||||
vid->b8000_limit = 0x8000;
|
||||
vid->planar_ctrl = 4;
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
io_sethandler(0x0065, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
} else
|
||||
vid->b8000_mask = 0x3fff;
|
||||
|
||||
timer_add(&vid->timer, vid_poll, dev, 1);
|
||||
mem_mapping_add(&vid->mapping, 0xb8000, 0x08000,
|
||||
vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev);
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
|
||||
dev->vid = vid;
|
||||
}
|
||||
|
||||
const device_config_t vid_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "display_type",
|
||||
.description = "Display type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = TANDY_RGB,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "RGB", .value = TANDY_RGB },
|
||||
{ .description = "Composite", .value = TANDY_COMPOSITE },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t vid_device = {
|
||||
.name = "Tandy 1000",
|
||||
.internal_name = "tandy1000_video",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = vid_config
|
||||
};
|
||||
|
||||
const device_t vid_device_hx = {
|
||||
.name = "Tandy 1000 HX",
|
||||
.internal_name = "tandy1000_hx_video",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = vid_config
|
||||
};
|
||||
|
||||
const device_t vid_device_sl = {
|
||||
.name = "Tandy 1000SL2",
|
||||
.internal_name = "tandy1000_sl_video",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
static void
|
||||
eep_write(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
||||
@@ -1632,12 +785,12 @@ tandy_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
if (dev->is_hx) {
|
||||
io_removehandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev);
|
||||
if (val & 0x01)
|
||||
mem_mapping_disable(&dev->vid->mapping);
|
||||
else {
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev);
|
||||
mem_mapping_set_addr(&dev->vid->mapping, 0xb8000, 0x8000);
|
||||
}
|
||||
} else {
|
||||
@@ -1656,7 +809,7 @@ tandy_write(uint16_t addr, uint8_t val, void *priv)
|
||||
mem_mapping_set_addr(&dev->ram_mapping,
|
||||
((val >> 1) & 7) * 128 * 1024,
|
||||
0x20000);
|
||||
recalc_address_sl(dev);
|
||||
tandy_recalc_address_sl(dev);
|
||||
dev->ram_bank = val;
|
||||
break;
|
||||
|
||||
@@ -1805,10 +958,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
keyboard_set_table(scancode_tandy);
|
||||
io_sethandler(0x00a0, 1,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device, dev);
|
||||
device_add_ex(&tandy_1000_video_device, dev);
|
||||
device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device);
|
||||
break;
|
||||
|
||||
@@ -1817,10 +970,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
keyboard_set_table(scancode_tandy);
|
||||
io_sethandler(0x00a0, 1,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device_hx);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000hx_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device_hx, dev);
|
||||
device_add_ex(&tandy_1000hx_video_device, dev);
|
||||
device_add(&ncr8496_device);
|
||||
device_add(&eep_1000hx_device);
|
||||
break;
|
||||
@@ -1830,10 +983,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
init_rom(dev);
|
||||
io_sethandler(0xffe8, 8,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device_sl);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000sl_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device_sl, dev);
|
||||
device_add_ex(&tandy_1000sl_video_device, dev);
|
||||
device_add(&pssj_device);
|
||||
device_add(&eep_1000sl2_device);
|
||||
break;
|
||||
|
||||
@@ -85,7 +85,7 @@ static const device_config_t ibmpc_config[] = {
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
@@ -195,7 +195,7 @@ static const device_config_t ibmpc82_config[] = {
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
@@ -282,48 +282,103 @@ machine_pc82_init(const machine_t *model)
|
||||
static const device_config_t ibmxt_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5160_1501512_5000027",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1501512 (11/08/82)", .internal_name = "ibm5160_1501512_5000027", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } },
|
||||
{ .name = "1501512 (11/08/82) (Alt)", .internal_name = "ibm5160_1501512_6359116", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" } },
|
||||
{ .name = "5000026 (08/16/82)", .internal_name = "ibm5160_5000026_5000027", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" } },
|
||||
#if 0
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{
|
||||
.name = "1501512 (11/08/82)",
|
||||
.internal_name = "ibm5160_1501512_5000027",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "1501512 (11/08/82) (Alt)",
|
||||
.internal_name = "ibm5160_1501512_6359116",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "5000026 (08/16/82)",
|
||||
.internal_name = "ibm5160_5000026_5000027",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" }
|
||||
},
|
||||
|
||||
// GlaBIOS for IBM XT
|
||||
{ .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "" } },
|
||||
{ .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "" } },
|
||||
{
|
||||
.name = "GlaBIOS 0.2.5 (8088)",
|
||||
.internal_name = "glabios_025_8088",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 1,
|
||||
.size = 40960,
|
||||
.files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "GlaBIOS 0.2.5 (V20)",
|
||||
.internal_name = "glabios_025_v20",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 1,
|
||||
.size = 40960,
|
||||
.files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
#endif
|
||||
{
|
||||
.name = "Supersoft Diagnostics",
|
||||
.internal_name = "diag_supersoft",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/Supersoft_PCXT_32KB.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "Ruud's Diagnostic Rom",
|
||||
.internal_name = "diag_ruuds",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_32kb.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "XT RAM Test",
|
||||
.internal_name = "diag_xtramtest",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/xtramtest_32k.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" }
|
||||
},
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "enable_basic",
|
||||
.name = "enable_basic",
|
||||
.description = "IBM Cassette Basic",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -351,6 +406,8 @@ machine_xt_init(const machine_t *model)
|
||||
uint8_t enable_5161;
|
||||
uint8_t enable_basic;
|
||||
const char *fn;
|
||||
uint16_t offset = 0;
|
||||
uint32_t local = 0;
|
||||
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
@@ -360,11 +417,17 @@ machine_xt_init(const machine_t *model)
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
enable_basic = machine_get_config_int("enable_basic");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000);
|
||||
local = device_get_bios_local(model->device, device_get_config_bios("bios"));
|
||||
|
||||
if (local == 0) // Offset for stock roms
|
||||
offset = 0x6000;
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, offset);
|
||||
|
||||
if (enable_basic && ret) {
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
if (local == 0) { // needed for stock roms
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
}
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1);
|
||||
/* On the real machine, the BASIC is repeated. */
|
||||
(void) bios_load_aux_linear(fn, 0x000f0000, 8192, 0);
|
||||
@@ -408,42 +471,98 @@ machine_genxt_init(const machine_t *model)
|
||||
static const device_config_t ibmxt86_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5160_050986",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1501512 (05/09/86)", .internal_name = "ibm5160_050986", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } },
|
||||
{ .name = "5000026 (01/10/86)", .internal_name = "ibm5160_011086", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" } },
|
||||
{ .name = "1501512 (01/10/86) (Alt)", .internal_name = "ibm5160_011086_alt", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" } },
|
||||
#if 0
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{
|
||||
.name = "1501512 (05/09/86)",
|
||||
.internal_name = "ibm5160_050986",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "5000026 (01/10/86)",
|
||||
.internal_name = "ibm5160_011086",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "1501512 (01/10/86) (Alt)",
|
||||
.internal_name = "ibm5160_011086_alt",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 0,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" }
|
||||
},
|
||||
|
||||
// GlaBIOS for IBM XT
|
||||
{ .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "" } },
|
||||
{ .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "" } },
|
||||
{
|
||||
.name = "GlaBIOS 0.2.5 (8088)",
|
||||
.internal_name = "glabios_025_8088",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 1,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "GlaBIOS 0.2.5 (V20)",
|
||||
.internal_name = "glabios_025_v20",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 1,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
#endif
|
||||
{
|
||||
.name = "Supersoft Diagnostics",
|
||||
.internal_name = "diag_supersoft",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/Supersoft_PCXT_32KB.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "Ruud's Diagnostic Rom",
|
||||
.internal_name = "diag_ruuds",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_32kb.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
{
|
||||
.name = "XT RAM Test",
|
||||
.internal_name = "diag_xtramtest",
|
||||
.bios_type = BIOS_NORMAL,
|
||||
.files_no = 2,
|
||||
.local = 2,
|
||||
.size = 65536,
|
||||
.files = { "roms/machines/diagnostic/xtramtest_32k.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" }
|
||||
},
|
||||
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -470,6 +589,8 @@ machine_xt86_init(const machine_t *model)
|
||||
int ret = 0;
|
||||
uint8_t enable_5161;
|
||||
const char *fn;
|
||||
uint16_t offset = 0;
|
||||
uint32_t local = 0;
|
||||
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
@@ -478,11 +599,17 @@ machine_xt86_init(const machine_t *model)
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000);
|
||||
local = device_get_bios_local(model->device, device_get_config_bios("bios"));
|
||||
|
||||
if (local == 0) // Offset for stock roms
|
||||
offset = 0x6000;
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, offset);
|
||||
|
||||
if (ret) {
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
if (local == 0) { // needed for stock roms
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
}
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1);
|
||||
(void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0);
|
||||
}
|
||||
|
||||
@@ -1918,7 +1918,7 @@ m19_vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
/* activating plantronics mode */
|
||||
if (addr == 0x3dd) {
|
||||
/* already in graphics mode */
|
||||
if ((val & 0x30) && (vid->ogc.cga.cgamode & 0x2))
|
||||
if ((val & 0x30) && (vid->ogc.cga.cgamode & CGA_MODE_FLAG_GRAPHICS))
|
||||
vid->mode = PLANTRONICS_MODE;
|
||||
else
|
||||
vid->mode = OLIVETTI_OGC_MODE;
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
// Temporarily here till we move everything out into the right files
|
||||
extern const device_t pcjr_device;
|
||||
extern const device_t m19_vid_device;
|
||||
extern const device_t vid_device;
|
||||
extern const device_t vid_device_hx;
|
||||
extern const device_t tandy_1000_video_device;
|
||||
extern const device_t tandy_1000hx_video_device;
|
||||
extern const device_t tandy_1000sl_video_device;
|
||||
|
||||
extern const device_t t1000_video_device;
|
||||
extern const device_t xi8088_device;
|
||||
extern const device_t cga_device;
|
||||
@@ -50,7 +52,6 @@ extern const device_t vid_pc2086_device;
|
||||
extern const device_t vid_pc3086_device;
|
||||
extern const device_t vid_200_device;
|
||||
extern const device_t vid_ppc512_device;
|
||||
extern const device_t vid_device_sl;
|
||||
extern const device_t t1200_video_device;
|
||||
extern const device_t compaq_plasma_device;
|
||||
extern const device_t ps1_2011_device;
|
||||
@@ -69,6 +70,7 @@ extern const device_t ap5s_device;
|
||||
extern const device_t d842_device;
|
||||
extern const device_t d943_device;
|
||||
extern const device_t dells333sl_device;
|
||||
extern const device_t hot433a_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -1590,7 +1592,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device,
|
||||
.vid_device = &tandy_1000_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -1629,7 +1631,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device_hx,
|
||||
.vid_device = &tandy_1000hx_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -2530,7 +2532,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device_sl,
|
||||
.vid_device = &tandy_1000sl_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -3415,6 +3417,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
.name = "[C&T PC/AT] Tulip AT Compact",
|
||||
.internal_name = "tuliptc7",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_CT_AT,
|
||||
.init = machine_at_tuliptc7_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_286,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 6000000,
|
||||
.max_bus = 12000000,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has Quadtel KBC firmware. */
|
||||
{
|
||||
.name = "[GC103] Quadtel 286 clone",
|
||||
@@ -3650,7 +3693,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = ¶dise_pvga1a_ncr3302_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -6605,6 +6648,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */
|
||||
{
|
||||
.name = "[VLSI 82C486] Tulip 486 DC/DT",
|
||||
.internal_name = "tuliptc38",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_VLSI_VL82C486,
|
||||
.init = machine_at_tuliptc38_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 2048,
|
||||
.max = 32768,
|
||||
.step = 2048
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/
|
||||
.vid_device = &gd5426_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has IBM PS/2 Type 1 KBC firmware. */
|
||||
{
|
||||
.name = "[MCA] IBM PS/2 model 70 (type 4)",
|
||||
@@ -9036,6 +9119,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in
|
||||
in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */
|
||||
{
|
||||
.name = "[UMC 8881] Biostar MB-84xxUUD-A",
|
||||
.internal_name = "84xxuuda",
|
||||
.type = MACHINE_TYPE_486_S3_PCI,
|
||||
.chipset = MACHINE_CHIPSET_UMC_UM8881,
|
||||
.init = machine_at_84xxuuda_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET3,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 131072,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 255,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has an AMIKey-2, which is an updated version of type 'H'. */
|
||||
{
|
||||
.name = "[UMC 8881] ECS Elite UM8810P-AIO",
|
||||
@@ -9112,7 +9236,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = &tgui9440_onboard_pci_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -9153,7 +9277,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = &gd5430_onboard_pci_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -9259,7 +9383,7 @@ const machine_t machines[] = {
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PCI,
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
@@ -9271,7 +9395,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &hot433a_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
|
||||
@@ -291,8 +291,12 @@ net_slirp_get_revents(int idx, void *opaque)
|
||||
WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT);
|
||||
WSA_TO_POLL(FD_CONNECT, SLIRP_POLL_OUT);
|
||||
WSA_TO_POLL(FD_OOB, SLIRP_POLL_PRI);
|
||||
WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_IN);
|
||||
WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_HUP);
|
||||
|
||||
if (ret == 0)
|
||||
ret |= SLIRP_POLL_IN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
||||
19
src/pic.c
19
src/pic.c
@@ -638,6 +638,25 @@ pic_reset_hard(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pic_toggle_latch(int is_ps2)
|
||||
{
|
||||
pic_kbd_latch(0x00);
|
||||
pic_mouse_latch(0x00);
|
||||
|
||||
/* Explicitly reset the latches. */
|
||||
kbd_latch = mouse_latch = 0;
|
||||
latched_irqs = 0x0000;
|
||||
|
||||
/* The situation is as follows: There is a giant mess when it comes to these latches on real hardware,
|
||||
to the point that there's even boards with board-level latched that get used in place of the latches
|
||||
on the chipset, therefore, I'm just doing this here for the sake of simplicity. */
|
||||
if (is_ps2) {
|
||||
pic_kbd_latch(0x01);
|
||||
pic_mouse_latch(0x01);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pic_init(void)
|
||||
{
|
||||
|
||||
@@ -598,7 +598,10 @@ msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
msgid "ISA Memory Expansion"
|
||||
msgstr "Карта расширения памяти ISA"
|
||||
msgstr "Карты расширения памяти ISA"
|
||||
|
||||
msgid "ISA ROM Cards"
|
||||
msgstr "Карты ПЗУ ISA"
|
||||
|
||||
msgid "Card 1:"
|
||||
msgstr "Карта 1:"
|
||||
@@ -1237,7 +1240,7 @@ msgid "Pen"
|
||||
msgstr "Ручка"
|
||||
|
||||
msgid "Host CD/DVD Drive (%1:)"
|
||||
msgstr "CD/DVD-привод хоста (%1:)"
|
||||
msgstr "CD/DVD Привод хоста (%1:)"
|
||||
|
||||
msgid "&Connected"
|
||||
msgstr "&Кабель подключен"
|
||||
@@ -1249,7 +1252,7 @@ msgid "Create..."
|
||||
msgstr "Создать..."
|
||||
|
||||
msgid "Host CD/DVD Drive (%1)"
|
||||
msgstr "CD/DVD-привод хоста (%1)"
|
||||
msgstr "CD/DVD Привод хоста (%1)"
|
||||
|
||||
msgid "Unknown Bus"
|
||||
msgstr "Неизвестная шина"
|
||||
@@ -1413,12 +1416,54 @@ msgstr "Системный MIDI"
|
||||
msgid "MIDI Input Device"
|
||||
msgstr "Устройство ввода MIDI"
|
||||
|
||||
msgid "BIOS file"
|
||||
msgstr "Файл BIOS"
|
||||
|
||||
msgid "BIOS file (ROM #1)"
|
||||
msgstr "Файл BIOS (ПЗУ #1)"
|
||||
|
||||
msgid "BIOS file (ROM #2)"
|
||||
msgstr "Файл BIOS (ПЗУ #2)"
|
||||
|
||||
msgid "BIOS file (ROM #3)"
|
||||
msgstr "Файл BIOS (ПЗУ #3)"
|
||||
|
||||
msgid "BIOS file (ROM #4)"
|
||||
msgstr "Файл BIOS (ПЗУ #4)"
|
||||
|
||||
msgid "BIOS Address"
|
||||
msgstr "Адрес BIOS"
|
||||
|
||||
msgid "BIOS address (ROM #1)"
|
||||
msgstr "Адрес BIOS (ПЗУ #1)"
|
||||
|
||||
msgid "BIOS address (ROM #2)"
|
||||
msgstr "Адрес BIOS (ПЗУ #2)"
|
||||
|
||||
msgid "BIOS address (ROM #3)"
|
||||
msgstr "Адрес BIOS (ПЗУ #3)"
|
||||
|
||||
msgid "BIOS address (ROM #4)"
|
||||
msgstr "Адрес BIOS (ПЗУ #4)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes"
|
||||
msgstr "Разрешить запись в ПЗУ расширения BIOS"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #1)"
|
||||
msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #1)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #2)"
|
||||
msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #2)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #3)"
|
||||
msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #3)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #4)"
|
||||
msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #4)"
|
||||
|
||||
msgid "Linear framebuffer base"
|
||||
msgstr "Линейная база кадрового буфера"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Адрес"
|
||||
|
||||
@@ -1428,6 +1473,21 @@ msgstr "IRQ"
|
||||
msgid "BIOS Revision"
|
||||
msgstr "Версия BIOS"
|
||||
|
||||
msgid "BIOS Version"
|
||||
msgstr "Версия BIOS"
|
||||
|
||||
msgid "BIOS Versions"
|
||||
msgstr "Версии BIOS"
|
||||
|
||||
msgid "BIOS Language"
|
||||
msgstr "Язык BIOS"
|
||||
|
||||
msgid "IBM 5161 Expansion Unit"
|
||||
msgstr "Блок расширения IBM 5161"
|
||||
|
||||
msgid "IBM Cassette Basic"
|
||||
msgstr "Кассетный бейсик IBM"
|
||||
|
||||
msgid "Translate 26 -> 17"
|
||||
msgstr "Переводить 26 -> 17"
|
||||
|
||||
@@ -1443,6 +1503,18 @@ msgstr "Инвертировать цвета"
|
||||
msgid "BIOS size"
|
||||
msgstr "Размер BIOS"
|
||||
|
||||
msgid "BIOS size (ROM #1)"
|
||||
msgstr "Размер BIOS (ПЗУ #1)"
|
||||
|
||||
msgid "BIOS size (ROM #2)"
|
||||
msgstr "Размер BIOS (ПЗУ #2)"
|
||||
|
||||
msgid "BIOS size (ROM #3)"
|
||||
msgstr "Размер BIOS (ПЗУ #3)"
|
||||
|
||||
msgid "BIOS size (ROM #4)"
|
||||
msgstr "Размер BIOS (ПЗУ #4)"
|
||||
|
||||
msgid "Map C0000-C7FFF as UMB"
|
||||
msgstr "Отображение C0000-C7FFF в качестве UMB"
|
||||
|
||||
@@ -1518,6 +1590,9 @@ msgstr "Уровень реверберации"
|
||||
msgid "Interpolation Method"
|
||||
msgstr "Метод интерполяции"
|
||||
|
||||
msgid "Dynamic Sample Loading"
|
||||
msgstr "Динамическая загрузка сэмплов"
|
||||
|
||||
msgid "Reverb Output Gain"
|
||||
msgstr "Усиление выходного сигнала ревербератора"
|
||||
|
||||
@@ -1606,7 +1681,7 @@ msgid "Enable Game port"
|
||||
msgstr "Включить игровой порт"
|
||||
|
||||
msgid "Surround module"
|
||||
msgstr "Модуль объемного звучания"
|
||||
msgstr "Модуль объёмного звучания"
|
||||
|
||||
msgid "CODEC"
|
||||
msgstr "Кодек"
|
||||
@@ -1617,6 +1692,9 @@ msgstr "Поднимать прерывание кодека при настро
|
||||
msgid "SB Address"
|
||||
msgstr "Адрес SB"
|
||||
|
||||
msgid "Use EEPROM setting"
|
||||
msgstr "Использовать настройку EEPROM"
|
||||
|
||||
msgid "WSS IRQ"
|
||||
msgstr "IRQ WSS"
|
||||
|
||||
@@ -1701,6 +1779,9 @@ msgstr "Тип RAMDAC"
|
||||
msgid "Blend"
|
||||
msgstr "Смесь"
|
||||
|
||||
msgid "Font"
|
||||
msgstr "Шрифт"
|
||||
|
||||
msgid "Bilinear filtering"
|
||||
msgstr "Билинейная фильтрация"
|
||||
|
||||
@@ -1746,6 +1827,33 @@ msgstr "Скорость передачи данных"
|
||||
msgid "EMS mode"
|
||||
msgstr "Режим EMS"
|
||||
|
||||
msgid "EMS Address"
|
||||
msgstr "Адрес EMS"
|
||||
|
||||
msgid "EMS 1 Address"
|
||||
msgstr "Адрес EMS 1"
|
||||
|
||||
msgid "EMS 2 Address"
|
||||
msgstr "Адрес EMS 2"
|
||||
|
||||
msgid "EMS Memory Size"
|
||||
msgstr "Размер памяти EMS"
|
||||
|
||||
msgid "EMS 1 Memory Size"
|
||||
msgstr "Размер памяти EMS 1"
|
||||
|
||||
msgid "EMS 2 Memory Size"
|
||||
msgstr "Размер памяти EMS 2"
|
||||
|
||||
msgid "Enable EMS"
|
||||
msgstr "Включить EMS"
|
||||
|
||||
msgid "Enable EMS 1"
|
||||
msgstr "Включить EMS 1"
|
||||
|
||||
msgid "Enable EMS 2"
|
||||
msgstr "Включить EMS 2"
|
||||
|
||||
msgid "Address for > 2 MB"
|
||||
msgstr "Адрес для > 2 МБ"
|
||||
|
||||
@@ -1765,10 +1873,10 @@ msgid "BIOS setting + Hotkeys (off during POST)"
|
||||
msgstr "Настройка BIOS + горячие клавиши (отключается во время POST)"
|
||||
|
||||
msgid "64 kB starting from F0000"
|
||||
msgstr "64 кБ, начиная с F0000"
|
||||
msgstr "64 КБ, начиная с F0000"
|
||||
|
||||
msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)"
|
||||
msgstr "128 кБ, начиная с E0000 (адрес MSB инвертирован, сначала последние 64 КБ)"
|
||||
msgstr "128 КБ, начиная с E0000 (адрес MSB инвертирован, сначала последние 64 КБ)"
|
||||
|
||||
msgid "Sine"
|
||||
msgstr "Синусоидальная"
|
||||
@@ -1792,7 +1900,7 @@ msgid "45 Hz (JMP2 not populated)"
|
||||
msgstr "45 Гц (без джампера на JMP2)"
|
||||
|
||||
msgid "Two"
|
||||
msgstr "Два"
|
||||
msgstr "Две"
|
||||
|
||||
msgid "Three"
|
||||
msgstr "Три"
|
||||
@@ -1935,6 +2043,9 @@ msgstr "Янтарный"
|
||||
msgid "Gray"
|
||||
msgstr "Серый"
|
||||
|
||||
msgid "Grayscale"
|
||||
msgstr "Монохромный"
|
||||
|
||||
msgid "Color"
|
||||
msgstr "Цветной"
|
||||
|
||||
@@ -1950,6 +2061,12 @@ msgstr "Другие языки"
|
||||
msgid "Bochs latest"
|
||||
msgstr "Bochs последний"
|
||||
|
||||
msgid "Apply overscan deltas"
|
||||
msgstr "Применить дельты вылетов развёртки"
|
||||
|
||||
msgid "Mono Interlaced"
|
||||
msgstr "Монохромный с чересстрочной развёрткой"
|
||||
|
||||
msgid "Mono Non-Interlaced"
|
||||
msgstr "Монохромный без чересстрочной развёртки"
|
||||
|
||||
@@ -2095,7 +2212,7 @@ msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for t
|
||||
msgstr "Шрифты TrueType в каталоге \"roms/printer/fonts\" необходимы для эмуляции стандартного матричного принтера ESC/P."
|
||||
|
||||
msgid "Inhibit multimedia keys"
|
||||
msgstr "Перехватывать мультимедиа-клавиши"
|
||||
msgstr "Перехватывать мультимедийные клавиши"
|
||||
|
||||
msgid "Ask for confirmation before saving settings"
|
||||
msgstr "Запрашивать подтверждение перед сохранением настроек"
|
||||
@@ -2182,7 +2299,7 @@ msgid "Send Control+Alt+Escape"
|
||||
msgstr "Отправить Control+Alt+Escape"
|
||||
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "Переключить на полноэкранный режим"
|
||||
msgstr "Переключить полноэкранный режим"
|
||||
|
||||
msgid "Screenshot"
|
||||
msgstr "Скриншот"
|
||||
|
||||
@@ -216,7 +216,7 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
|
||||
}
|
||||
|
||||
bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window);
|
||||
bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window || (kbd_req_capture && !mouse_capture));
|
||||
|
||||
if (skip)
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
|
||||
@@ -11,75 +11,134 @@
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2025 starfrost
|
||||
#
|
||||
|
||||
add_library(vid OBJECT
|
||||
|
||||
# Video Core
|
||||
agpgart.c
|
||||
video.c
|
||||
vid_table.c
|
||||
|
||||
# RAMDAC (Should this be its own library?)
|
||||
ramdac/vid_ramdac_ati68860.c
|
||||
ramdac/vid_ramdac_ati68875.c
|
||||
ramdac/vid_ramdac_att20c49x.c
|
||||
ramdac/vid_ramdac_att2xc498.c
|
||||
ramdac/vid_ramdac_bt48x.c
|
||||
ramdac/vid_ramdac_bt481.c
|
||||
ramdac/vid_ramdac_ibm_rgb528.c
|
||||
ramdac/vid_ramdac_sc1148x.c
|
||||
ramdac/vid_ramdac_sc1502x.c
|
||||
ramdac/vid_ramdac_sdac.c
|
||||
ramdac/vid_ramdac_stg1702.c
|
||||
ramdac/vid_ramdac_tkd8001.c
|
||||
ramdac/vid_ramdac_tvp3026.c
|
||||
|
||||
# Clock generator chips
|
||||
clockgen/vid_clockgen_av9194.c
|
||||
clockgen/vid_clockgen_icd2061.c
|
||||
clockgen/vid_clockgen_ics2494.c
|
||||
clockgen/vid_clockgen_ics2595.c
|
||||
|
||||
# DDC / monitor identification stuff
|
||||
vid_ddc.c
|
||||
|
||||
# CARDS start here
|
||||
|
||||
# CGA / Super CGA
|
||||
vid_cga.c
|
||||
vid_cga_comp.c
|
||||
vid_compaq_cga.c
|
||||
vid_cga_compaq.c
|
||||
vid_cga_compaq_plasma.c
|
||||
vid_cga_colorplus.c
|
||||
vid_cga_ncr.c
|
||||
vid_cga_olivetti.c
|
||||
vid_cga_toshiba_t1000.c
|
||||
vid_cga_toshiba_t3100e.c
|
||||
|
||||
# PCJr/Tandy
|
||||
vid_pcjr.c
|
||||
vid_tandy.c
|
||||
vid_mda.c
|
||||
|
||||
# Hercules
|
||||
vid_hercules.c
|
||||
vid_herculesplus.c
|
||||
vid_incolor.c
|
||||
vid_colorplus.c
|
||||
vid_hercules_plus.c
|
||||
vid_hercules_incolor.c
|
||||
|
||||
# Other early CGA-era cards
|
||||
vid_genius.c
|
||||
vid_sigma.c
|
||||
|
||||
# PGC / IM1024 / WY700 high-resolution
|
||||
vid_pgc.c
|
||||
vid_im1024.c
|
||||
vid_sigma.c
|
||||
vid_wy700.c
|
||||
|
||||
# EGA
|
||||
vid_ega.c
|
||||
vid_ega_render.c
|
||||
vid_svga.c
|
||||
vid_8514a.c
|
||||
vid_svga_render.c
|
||||
vid_ddc.c
|
||||
vid_jega.c
|
||||
|
||||
# (Real IBM) VGA
|
||||
vid_vga.c
|
||||
|
||||
# Super VGA core
|
||||
vid_svga.c
|
||||
vid_svga_render.c
|
||||
|
||||
# 8514/A, XGA and derivatives
|
||||
vid_8514a.c
|
||||
vid_xga.c
|
||||
vid_ps55da2.c
|
||||
|
||||
# ATI Technologies
|
||||
vid_ati_eeprom.c
|
||||
vid_ati18800.c
|
||||
vid_ati28800.c
|
||||
vid_ati_mach8.c
|
||||
vid_ati_mach64.c
|
||||
vid_ati68875_ramdac.c
|
||||
vid_ati68860_ramdac.c
|
||||
vid_bt481_ramdac.c
|
||||
vid_bt48x_ramdac.c
|
||||
|
||||
# Chips & Technologies
|
||||
vid_chips_69000.c
|
||||
vid_av9194.c
|
||||
vid_icd2061.c
|
||||
vid_ics2494.c
|
||||
vid_ics2595.c
|
||||
|
||||
# Cirrus Logic
|
||||
vid_cl54xx.c
|
||||
|
||||
# Tseng Labs
|
||||
vid_et3000.c
|
||||
vid_et4000.c
|
||||
vid_sc1148x_ramdac.c
|
||||
vid_sc1502x_ramdac.c
|
||||
vid_et4000w32.c
|
||||
vid_stg_ramdac.c
|
||||
|
||||
# Headland
|
||||
vid_ht216.c
|
||||
vid_oak_oti.c
|
||||
|
||||
# Paradise
|
||||
vid_paradise.c
|
||||
vid_rtg310x.c
|
||||
vid_f82c425.c
|
||||
vid_ti_cf62011.c
|
||||
vid_tvga.c vid_tgui9440.c
|
||||
vid_tkd8001_ramdac.c
|
||||
vid_att20c49x_ramdac.c
|
||||
vid_s3.c vid_s3_virge.c
|
||||
vid_ibm_rgb528_ramdac.c
|
||||
vid_sdac_ramdac.c
|
||||
vid_ogc.c
|
||||
|
||||
# Trident
|
||||
vid_tvga.c
|
||||
vid_tgui9440.c
|
||||
|
||||
# S3 Graphics
|
||||
vid_s3.c
|
||||
vid_s3_virge.c
|
||||
|
||||
# Matrox
|
||||
vid_mga.c
|
||||
vid_nga.c
|
||||
vid_tvp3026_ramdac.c
|
||||
vid_att2xc498_ramdac.c
|
||||
vid_xga.c
|
||||
vid_bochs_vbe.c
|
||||
vid_ps55da2.c
|
||||
vid_jega.c
|
||||
|
||||
# NVidia (pending)
|
||||
nv/nv_rivatimer.c
|
||||
|
||||
# Generic
|
||||
vid_bochs_vbe.c
|
||||
|
||||
)
|
||||
|
||||
if(G100)
|
||||
@@ -90,6 +149,7 @@ if(XL24)
|
||||
target_compile_definitions(vid PRIVATE USE_XL24)
|
||||
endif()
|
||||
|
||||
# 3Dfx Voodoo
|
||||
add_library(voodoo OBJECT
|
||||
vid_voodoo.c
|
||||
vid_voodoo_banshee.c
|
||||
|
||||
@@ -261,38 +261,57 @@ void
|
||||
ati68860_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
|
||||
int comb;
|
||||
int offset;
|
||||
uint8_t dat;
|
||||
int x_pos;
|
||||
int y_pos;
|
||||
int shift = 0;
|
||||
uint16_t dat;
|
||||
uint32_t col0 = ramdac->pallook[0];
|
||||
uint32_t col1 = ramdac->pallook[1];
|
||||
uint32_t *p;
|
||||
|
||||
offset = svga->dac_hwcursor_latch.xoff;
|
||||
for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) {
|
||||
dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)];
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
offset += 4;
|
||||
offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
|
||||
if (svga->packed_4bpp)
|
||||
shift = 1;
|
||||
|
||||
for (int x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += (8 >> shift)) {
|
||||
if (shift) {
|
||||
dat = svga->vram[(svga->dac_hwcursor_latch.addr) & svga->vram_mask] & 0x0f;
|
||||
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 4);
|
||||
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 2) & svga->vram_mask] << 8);
|
||||
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 3) & svga->vram_mask] << 12);
|
||||
} else {
|
||||
dat = svga->vram[svga->dac_hwcursor_latch.addr & svga->vram_mask];
|
||||
dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 8);
|
||||
}
|
||||
for (int xx = 0; xx < (8 >> shift); xx++) {
|
||||
comb = (dat >> (xx << 1)) & 0x03;
|
||||
|
||||
y_pos = displine;
|
||||
x_pos = offset + svga->x_add;
|
||||
p = buffer32->line[y_pos];
|
||||
|
||||
if (offset >= svga->dac_hwcursor_latch.x) {
|
||||
switch (comb) {
|
||||
case 0:
|
||||
p[x_pos] = col0;
|
||||
break;
|
||||
case 1:
|
||||
p[x_pos] = col1;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] ^= 0xffffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
svga->dac_hwcursor_latch.addr += 2;
|
||||
}
|
||||
|
||||
svga->dac_hwcursor_latch.addr += 16;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -104,7 +104,7 @@ ibm_rgb528_render_4bpp(svga_t *svga)
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
@@ -114,8 +114,8 @@ ibm_rgb528_render_4bpp(svga_t *svga)
|
||||
for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
if (vram_size == 3) {
|
||||
if (!(x & 31)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]);
|
||||
if (swap_word) {
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL);
|
||||
@@ -127,7 +127,7 @@ ibm_rgb528_render_4bpp(svga_t *svga)
|
||||
dat = (((x & 16) ? dat642 : dat64) >> (((x & 15) << 2) ^ 4)) & 0xf;
|
||||
} else if (vram_size == 1) {
|
||||
if (!(x & 15)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
if (swap_word)
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ ibm_rgb528_render_4bpp(svga_t *svga)
|
||||
dat = (dat64 >> (((x & 15) << 2) ^ 4)) & 0xf;
|
||||
} else {
|
||||
if (!(x & 7))
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->ma]);
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]);
|
||||
if (swap_nib)
|
||||
dat = (dat32 >> ((x & 7) << 2)) & 0xf;
|
||||
else
|
||||
@@ -156,11 +156,11 @@ ibm_rgb528_render_4bpp(svga_t *svga)
|
||||
p[x] = dat_out.pixel & 0xffffff;
|
||||
|
||||
if ((vram_size == 3) && ((x & 31) == 31))
|
||||
svga->ma = (svga->ma + 16) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask;
|
||||
if ((vram_size == 1) && ((x & 15) == 15))
|
||||
svga->ma = (svga->ma + 8) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask;
|
||||
else if ((!vram_size) && ((x & 7) == 7))
|
||||
svga->ma = (svga->ma + 4) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,7 @@ ibm_rgb528_render_8bpp(svga_t *svga)
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
@@ -192,8 +192,8 @@ ibm_rgb528_render_8bpp(svga_t *svga)
|
||||
for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
if (vram_size == 3) {
|
||||
if (!(x & 15)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]);
|
||||
if (swap_word) {
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL);
|
||||
@@ -202,14 +202,14 @@ ibm_rgb528_render_8bpp(svga_t *svga)
|
||||
dat = (((x & 8) ? dat642 : dat64) >> ((x & 7) << 3)) & 0xff;
|
||||
} else if (vram_size == 1) {
|
||||
if (!(x & 7)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
if (swap_word)
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
}
|
||||
dat = (dat64 >> ((x & 7) << 3)) & 0xff;
|
||||
} else {
|
||||
if (!(x & 3))
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->ma]);
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]);
|
||||
dat = (dat32 >> ((x & 3) << 3)) & 0xff;
|
||||
}
|
||||
if (b8_dcol == 0x00) {
|
||||
@@ -225,11 +225,11 @@ ibm_rgb528_render_8bpp(svga_t *svga)
|
||||
p[x] = dat_out.pixel & 0xffffff;
|
||||
|
||||
if ((vram_size == 3) && ((x & 15) == 15))
|
||||
svga->ma = (svga->ma + 16) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask;
|
||||
else if ((vram_size == 1) && ((x & 7) == 7))
|
||||
svga->ma = (svga->ma + 8) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask;
|
||||
else if ((!vram_size) && ((x & 3) == 3))
|
||||
svga->ma = (svga->ma + 4) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ ibm_rgb528_render_15_16bpp(svga_t *svga)
|
||||
if (b555_565 && (b16_dcol != 0x01))
|
||||
partition &= 0xc0;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
@@ -272,8 +272,8 @@ ibm_rgb528_render_15_16bpp(svga_t *svga)
|
||||
for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
if (vram_size == 2) {
|
||||
if (!(x & 7)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]);
|
||||
if (swap_word) {
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
dat642 = (dat64 << 32ULL) | (dat642 >> 32ULL);
|
||||
@@ -282,14 +282,14 @@ ibm_rgb528_render_15_16bpp(svga_t *svga)
|
||||
dat = (((x & 4) ? dat642 : dat64) >> ((x & 3) << 4)) & 0xffff;
|
||||
} else if (vram_size == 1) {
|
||||
if (!(x & 3)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
if (swap_word)
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
}
|
||||
dat = (dat64 >> ((x & 3) << 4)) & 0xffff;
|
||||
} else {
|
||||
if (!(x & 1))
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->ma]);
|
||||
dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]);
|
||||
dat = (dat32 >> ((x & 1) << 4)) & 0xffff;
|
||||
}
|
||||
dat_ex = (ibm_rgb528_pixel16_t *) &dat;
|
||||
@@ -350,11 +350,11 @@ ibm_rgb528_render_15_16bpp(svga_t *svga)
|
||||
p[x] = dat_out.pixel & 0xffffff;
|
||||
|
||||
if ((vram_size == 3) && ((x & 7) == 7))
|
||||
svga->ma = (svga->ma + 16) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask;
|
||||
else if ((vram_size == 1) && ((x & 3) == 3))
|
||||
svga->ma = (svga->ma + 8) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask;
|
||||
else if (!vram_size && ((x & 1) == 1))
|
||||
svga->ma = (svga->ma + 4) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +378,7 @@ ibm_rgb528_render_24bpp(svga_t *svga)
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
@@ -389,12 +389,12 @@ ibm_rgb528_render_24bpp(svga_t *svga)
|
||||
dat_ex = (ibm_rgb528_pixel32_t *) &dat;
|
||||
if (vram_size == 3) {
|
||||
if ((x & 15) == 0) {
|
||||
dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
|
||||
dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]);
|
||||
dat64[3] = *(uint64_t *) (&svga->vram[(svga->ma + 24) & svga->vram_display_mask]);
|
||||
dat64[4] = *(uint64_t *) (&svga->vram[(svga->ma + 32) & svga->vram_display_mask]);
|
||||
dat64[5] = *(uint64_t *) (&svga->vram[(svga->ma + 40) & svga->vram_display_mask]);
|
||||
dat64[0] = *(uint64_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]);
|
||||
dat64[1] = *(uint64_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]);
|
||||
dat64[2] = *(uint64_t *) (&svga->vram[(svga->memaddr + 16) & svga->vram_display_mask]);
|
||||
dat64[3] = *(uint64_t *) (&svga->vram[(svga->memaddr + 24) & svga->vram_display_mask]);
|
||||
dat64[4] = *(uint64_t *) (&svga->vram[(svga->memaddr + 32) & svga->vram_display_mask]);
|
||||
dat64[5] = *(uint64_t *) (&svga->vram[(svga->memaddr + 40) & svga->vram_display_mask]);
|
||||
if (swap_word) {
|
||||
dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL);
|
||||
dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL);
|
||||
@@ -407,9 +407,9 @@ ibm_rgb528_render_24bpp(svga_t *svga)
|
||||
dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[(x & 15) * 3]);
|
||||
} else if (vram_size == 1) {
|
||||
if ((x & 7) == 0) {
|
||||
dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
|
||||
dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]);
|
||||
dat64[0] = *(uint64_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]);
|
||||
dat64[1] = *(uint64_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]);
|
||||
dat64[2] = *(uint64_t *) (&svga->vram[(svga->memaddr + 16) & svga->vram_display_mask]);
|
||||
if (swap_word) {
|
||||
dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL);
|
||||
dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL);
|
||||
@@ -441,9 +441,9 @@ ibm_rgb528_render_24bpp(svga_t *svga)
|
||||
p[x] = dat_ex->pixel & 0xffffff;
|
||||
|
||||
if ((vram_size == 3) && ((x & 15) == 15))
|
||||
svga->ma = (svga->ma + 48) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 48) & svga->vram_display_mask;
|
||||
else if ((vram_size == 1) && ((x & 7) == 7))
|
||||
svga->ma = (svga->ma + 24) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 24) & svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,7 +468,7 @@ ibm_rgb528_render_32bpp(svga_t *svga)
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
@@ -478,8 +478,8 @@ ibm_rgb528_render_32bpp(svga_t *svga)
|
||||
for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
|
||||
if (vram_size == 3) {
|
||||
if (!(x & 3)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]);
|
||||
if (swap_word) {
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL);
|
||||
@@ -488,13 +488,13 @@ ibm_rgb528_render_32bpp(svga_t *svga)
|
||||
dat = (((x & 2) ? dat642 : dat64) >> ((x & 1ULL) << 5ULL)) & 0xffffffff;
|
||||
} else if (vram_size == 1) {
|
||||
if (!(x & 1)) {
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->ma]);
|
||||
dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]);
|
||||
if (swap_word)
|
||||
dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL);
|
||||
}
|
||||
dat = (dat64 >> ((x & 1ULL) << 5ULL)) & 0xffffffff;
|
||||
} else
|
||||
dat = *(uint32_t *) (&svga->vram[svga->ma]);
|
||||
dat = *(uint32_t *) (&svga->vram[svga->memaddr]);
|
||||
dat_ex = (ibm_rgb528_pixel32_t *) &dat;
|
||||
if (swaprb) {
|
||||
temp = dat_ex->r;
|
||||
@@ -520,11 +520,11 @@ ibm_rgb528_render_32bpp(svga_t *svga)
|
||||
p[x] = dat_ex->pixel & 0xffffff;
|
||||
|
||||
if ((vram_size == 3) && ((x & 3) == 3))
|
||||
svga->ma = (svga->ma + 16) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask;
|
||||
else if ((vram_size == 1) && ((x & 1) == 1))
|
||||
svga->ma = (svga->ma + 8) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask;
|
||||
else if (!vram_size)
|
||||
svga->ma = (svga->ma + 4) & svga->vram_display_mask;
|
||||
svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -3383,7 +3383,7 @@ ibm8514_render_8bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3391,22 +3391,22 @@ ibm8514_render_8bpp(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (int x = 0; x <= dev->h_disp; x += 8) {
|
||||
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]);
|
||||
p[0] = dev->pallook[dat & dev->dac_mask & 0xff];
|
||||
p[1] = dev->pallook[(dat >> 8) & dev->dac_mask & 0xff];
|
||||
p[2] = dev->pallook[(dat >> 16) & dev->dac_mask & 0xff];
|
||||
p[3] = dev->pallook[(dat >> 24) & dev->dac_mask & 0xff];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 4) & dev->vram_mask]);
|
||||
p[4] = dev->pallook[dat & dev->dac_mask & 0xff];
|
||||
p[5] = dev->pallook[(dat >> 8) & dev->dac_mask & 0xff];
|
||||
p[6] = dev->pallook[(dat >> 16) & dev->dac_mask & 0xff];
|
||||
p[7] = dev->pallook[(dat >> 24) & dev->dac_mask & 0xff];
|
||||
|
||||
dev->ma += 8;
|
||||
dev->memaddr += 8;
|
||||
p += 8;
|
||||
}
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3421,7 +3421,7 @@ ibm8514_render_15bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3429,24 +3429,24 @@ ibm8514_render_15bpp(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (x = 0; x <= dev->h_disp; x += 8) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1)) & dev->vram_mask]);
|
||||
p[x] = video_15to32[dat & 0xffff];
|
||||
p[x + 1] = video_15to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 4) & dev->vram_mask]);
|
||||
p[x + 2] = video_15to32[dat & 0xffff];
|
||||
p[x + 3] = video_15to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 8) & dev->vram_mask]);
|
||||
p[x + 4] = video_15to32[dat & 0xffff];
|
||||
p[x + 5] = video_15to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 12) & dev->vram_mask]);
|
||||
p[x + 6] = video_15to32[dat & 0xffff];
|
||||
p[x + 7] = video_15to32[dat >> 16];
|
||||
}
|
||||
dev->ma += (x << 1);
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr += (x << 1);
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3461,7 +3461,7 @@ ibm8514_render_16bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3469,24 +3469,24 @@ ibm8514_render_16bpp(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (x = 0; x <= dev->h_disp; x += 8) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1)) & dev->vram_mask]);
|
||||
p[x] = video_16to32[dat & 0xffff];
|
||||
p[x + 1] = video_16to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 4) & dev->vram_mask]);
|
||||
p[x + 2] = video_16to32[dat & 0xffff];
|
||||
p[x + 3] = video_16to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 8) & dev->vram_mask]);
|
||||
p[x + 4] = video_16to32[dat & 0xffff];
|
||||
p[x + 5] = video_16to32[dat >> 16];
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 1) + 12) & dev->vram_mask]);
|
||||
p[x + 6] = video_16to32[dat & 0xffff];
|
||||
p[x + 7] = video_16to32[dat >> 16];
|
||||
}
|
||||
dev->ma += (x << 1);
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr += (x << 1);
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3500,7 +3500,7 @@ ibm8514_render_24bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3508,21 +3508,21 @@ ibm8514_render_24bpp(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (int x = 0; x <= dev->h_disp; x += 4) {
|
||||
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]);
|
||||
p[x] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]);
|
||||
p[x + 1] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]);
|
||||
p[x + 2] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]);
|
||||
p[x + 3] = dat & 0xffffff;
|
||||
|
||||
dev->ma += 12;
|
||||
dev->memaddr += 12;
|
||||
}
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3536,7 +3536,7 @@ ibm8514_render_BGR(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3544,21 +3544,21 @@ ibm8514_render_BGR(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (int x = 0; x <= dev->h_disp; x += 4) {
|
||||
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]);
|
||||
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]);
|
||||
p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]);
|
||||
p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]);
|
||||
p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dev->ma += 12;
|
||||
dev->memaddr += 12;
|
||||
}
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3573,7 +3573,7 @@ ibm8514_render_ABGR8888(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3581,11 +3581,11 @@ ibm8514_render_ABGR8888(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (x = 0; x <= dev->h_disp; x++) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]);
|
||||
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
}
|
||||
dev->ma += (x * 4);
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr += (x * 4);
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3600,7 +3600,7 @@ ibm8514_render_32bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || dev->changedvram[(dev->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || dev->changedvram[(dev->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -3608,11 +3608,11 @@ ibm8514_render_32bpp(svga_t *svga)
|
||||
dev->lastline_draw = dev->displine;
|
||||
|
||||
for (x = 0; x <= dev->h_disp; x++) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]);
|
||||
p[x] = dat & 0xffffff;
|
||||
}
|
||||
dev->ma += (x * 4);
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr += (x * 4);
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3681,7 +3681,7 @@ ibm8514_poll(void *priv)
|
||||
if (dev->dispon) {
|
||||
dev->hdisp_on = 1;
|
||||
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
|
||||
if (dev->firstline == 2000) {
|
||||
dev->firstline = dev->displine;
|
||||
@@ -3689,14 +3689,14 @@ ibm8514_poll(void *priv)
|
||||
}
|
||||
|
||||
if (dev->hwcursor_on)
|
||||
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
|
||||
dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2;
|
||||
|
||||
svga->render8514(svga);
|
||||
|
||||
svga->x_add = (overscan_x >> 1);
|
||||
svga->x_add = svga->left_overscan;
|
||||
ibm8514_render_overscan_left(dev, svga);
|
||||
ibm8514_render_overscan_right(dev, svga);
|
||||
svga->x_add = (overscan_x >> 1);
|
||||
svga->x_add = svga->left_overscan;
|
||||
|
||||
if (dev->hwcursor_on) {
|
||||
if (svga->hwcursor_draw)
|
||||
@@ -3726,18 +3726,18 @@ ibm8514_poll(void *priv)
|
||||
|
||||
dev->linepos = 0;
|
||||
if (dev->dispon) {
|
||||
if (dev->sc == dev->rowcount) {
|
||||
dev->sc = 0;
|
||||
dev->maback += (dev->rowoffset << 3);
|
||||
if (dev->scanline == dev->rowcount) {
|
||||
dev->scanline = 0;
|
||||
dev->memaddr_backup += (dev->rowoffset << 3);
|
||||
if (dev->interlace)
|
||||
dev->maback += (dev->rowoffset << 3);
|
||||
dev->memaddr_backup += (dev->rowoffset << 3);
|
||||
|
||||
dev->maback &= dev->vram_mask;
|
||||
dev->ma = dev->maback;
|
||||
dev->memaddr_backup &= dev->vram_mask;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 0x1f;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 0x1f;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3783,20 +3783,20 @@ ibm8514_poll(void *priv)
|
||||
svga->vslines = 0;
|
||||
|
||||
if (dev->interlace && dev->oddeven)
|
||||
dev->ma = dev->maback = (dev->rowoffset << 1);
|
||||
dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1);
|
||||
else
|
||||
dev->ma = dev->maback = 0;
|
||||
dev->memaddr = dev->memaddr_backup = 0;
|
||||
|
||||
dev->ma = (dev->ma << 2);
|
||||
dev->maback = (dev->maback << 2);
|
||||
dev->memaddr = (dev->memaddr << 2);
|
||||
dev->memaddr_backup = (dev->memaddr_backup << 2);
|
||||
}
|
||||
if (dev->vc == dev->v_total) {
|
||||
dev->vc = 0;
|
||||
dev->sc = (svga->crtc[0x8] & 0x1f);
|
||||
dev->scanline = (svga->crtc[0x8] & 0x1f);
|
||||
dev->dispon = 1;
|
||||
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
|
||||
|
||||
svga->x_add = (overscan_x >> 1);
|
||||
svga->x_add = svga->left_overscan;
|
||||
|
||||
dev->hwcursor_on = 0;
|
||||
dev->hwcursor_latch = dev->hwcursor;
|
||||
@@ -3966,7 +3966,7 @@ ibm8514_init(const device_t *info)
|
||||
bios_addr = 0xc6000;
|
||||
|
||||
switch (dev->extensions) {
|
||||
case 1:
|
||||
case ATI:
|
||||
if (rom_present(BIOS_MACH8_ROM_PATH)) {
|
||||
mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t));
|
||||
svga->ext8514 = mach;
|
||||
@@ -3977,13 +3977,14 @@ ibm8514_init(const device_t *info)
|
||||
0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
ati8514_init(svga, svga->ext8514, svga->dev8514);
|
||||
mach->accel.scratch0 = ((((bios_addr >> 7) - 0x1000) >> 4));
|
||||
mach->accel.scratch0 = ((bios_addr >> 7) - 0x1000) >> 4;
|
||||
bios_rom_eeprom = mach->accel.scratch0;
|
||||
if (dev->type & DEVICE_MCA) {
|
||||
dev->pos_regs[0] = 0x88;
|
||||
dev->pos_regs[1] = 0x80;
|
||||
mach->eeprom.data[0] = 0x0000;
|
||||
mach->eeprom.data[1] = bios_rom_eeprom | ((bios_rom_eeprom | 0x01) << 8);
|
||||
ibm8514_log("EEPROM Data1=%04x.\n", mach->eeprom.data[1]);
|
||||
mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
|
||||
ati_eeprom_load_mach8(&mach->eeprom, "ati8514_mca.nvr", 1);
|
||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||
@@ -4067,12 +4068,12 @@ static const device_config_t isa_ext8514_config[] = {
|
||||
.description = "Vendor",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.default_int = IBM,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IBM", .value = 0 },
|
||||
{ .description = "ATI", .value = 1 },
|
||||
{ .description = "IBM", .value = IBM },
|
||||
{ .description = "ATI", .value = ATI },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
@@ -4127,12 +4128,12 @@ static const device_config_t mca_ext8514_config[] = {
|
||||
.description = "Vendor",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.default_int = IBM,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IBM", .value = 0 },
|
||||
{ .description = "ATI", .value = 1 },
|
||||
{ .description = "IBM", .value = IBM },
|
||||
{ .description = "ATI", .value = ATI },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
@@ -4145,7 +4146,7 @@ const device_t gen8514_isa_device = {
|
||||
.name = "IBM 8514/A clone (ISA)",
|
||||
.internal_name = "8514_isa",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0,
|
||||
.local = IBM_8514A_TYPE,
|
||||
.init = ibm8514_init,
|
||||
.close = ibm8514_close,
|
||||
.reset = NULL,
|
||||
@@ -4159,7 +4160,7 @@ const device_t ibm8514_mca_device = {
|
||||
.name = "IBM 8514/A (MCA)",
|
||||
.internal_name = "8514_mca",
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 0,
|
||||
.local = IBM_8514A_TYPE,
|
||||
.init = ibm8514_init,
|
||||
.close = ibm8514_close,
|
||||
.reset = NULL,
|
||||
|
||||
@@ -109,7 +109,7 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -223,7 +223,7 @@ ati18800_recalctimings(svga_t *svga)
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ ati28800_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -416,10 +416,10 @@ ati28800_recalctimings(svga_t *svga)
|
||||
((ati28800->regs[0xb9] & 2) << 1);
|
||||
|
||||
if (ati28800->regs[0xa3] & 0x10)
|
||||
svga->ma_latch |= 0x10000;
|
||||
svga->memaddr_latch |= 0x10000;
|
||||
|
||||
if (ati28800->regs[0xb0] & 0x40)
|
||||
svga->ma_latch |= 0x20000;
|
||||
svga->memaddr_latch |= 0x20000;
|
||||
|
||||
if (ati28800->regs[0xb8] & 0x40)
|
||||
svga->clock *= 2;
|
||||
@@ -483,7 +483,7 @@ ati28800_recalctimings(svga_t *svga)
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
@@ -496,7 +496,7 @@ ati28800_recalctimings(svga_t *svga)
|
||||
svga->hdisp >>= 1;
|
||||
svga->dots_per_clock >>= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -456,7 +456,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -524,14 +524,18 @@ mach64_recalctimings(svga_t *svga)
|
||||
svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
|
||||
svga->rowoffset = (mach64->crtc_off_pitch >> 22);
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen);
|
||||
svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
|
||||
svga->memaddr_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2;
|
||||
svga->linedbl = svga->rowcount = 0;
|
||||
svga->split = 0xffffff;
|
||||
svga->vblankstart = svga->dispend;
|
||||
svga->rowcount = mach64->crtc_gen_cntl & 1;
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
if (mach64->type == MACH64_GX)
|
||||
ati68860_ramdac_set_render(svga->ramdac, svga);
|
||||
|
||||
svga->packed_4bpp = !!(((mach64->crtc_gen_cntl >> 8) & 7) == BPP_4);
|
||||
|
||||
switch ((mach64->crtc_gen_cntl >> 8) & 7) {
|
||||
case BPP_4:
|
||||
if (mach64->type != MACH64_GX)
|
||||
@@ -572,8 +576,9 @@ mach64_recalctimings(svga_t *svga)
|
||||
}
|
||||
|
||||
svga->vram_display_mask = mach64->vram_mask;
|
||||
} else
|
||||
} else {
|
||||
svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2310,6 +2315,7 @@ uint8_t
|
||||
mach64_ext_readb(uint32_t addr, void *priv)
|
||||
{
|
||||
mach64_t *mach64 = (mach64_t *) priv;
|
||||
svga_t *svga = &mach64->svga;
|
||||
|
||||
uint8_t ret = 0xff;
|
||||
if (!(addr & 0x400)) {
|
||||
@@ -2524,8 +2530,22 @@ mach64_ext_readb(uint32_t addr, void *priv)
|
||||
case 0xc3:
|
||||
if (mach64->type == MACH64_GX)
|
||||
ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
||||
else
|
||||
ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga);
|
||||
else {
|
||||
switch (addr & 3) {
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
@@ -2962,7 +2982,7 @@ mach64_ext_readl(uint32_t addr, void *priv)
|
||||
uint32_t ret;
|
||||
|
||||
if (!(addr & 0x400)) {
|
||||
mach64_log("nmach64_ext_readl: addr=%04x\n", addr);
|
||||
mach64_log("mach64_ext_readl: addr=%04x\n", addr);
|
||||
ret = 0xffffffff;
|
||||
} else
|
||||
switch (addr & 0x3ff) {
|
||||
@@ -3101,6 +3121,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
} else if (addr & 0x300) {
|
||||
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
|
||||
} else {
|
||||
mach64_log("mach64_ext_writeb: addr=%04x val=%02x\n", addr & 0x3ff, val);
|
||||
switch (addr & 0x3ff) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
@@ -3189,39 +3210,48 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
WRITE8(addr, mach64->cur_clr0, val);
|
||||
if (mach64->type == MACH64_VT2)
|
||||
ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff));
|
||||
break;
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
WRITE8(addr, mach64->cur_clr1, val);
|
||||
if (mach64->type == MACH64_VT2)
|
||||
ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff));
|
||||
break;
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
WRITE8(addr, mach64->cur_offset, val);
|
||||
svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8;
|
||||
if (mach64->type == MACH64_GX)
|
||||
svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3;
|
||||
else
|
||||
svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3;
|
||||
break;
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
WRITE8(addr, mach64->cur_horz_vert_posn, val);
|
||||
svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
||||
svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
||||
if (mach64->type == MACH64_GX) {
|
||||
svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
||||
svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
||||
} else {
|
||||
svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
|
||||
svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
|
||||
}
|
||||
break;
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
WRITE8(addr, mach64->cur_horz_vert_off, val);
|
||||
svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
||||
svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
||||
if (mach64->type == MACH64_GX) {
|
||||
svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
||||
svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
||||
} else {
|
||||
svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
|
||||
svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
@@ -3283,8 +3313,22 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
case 0xc3:
|
||||
if (mach64->type == MACH64_GX)
|
||||
ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
||||
else
|
||||
ati68860_ramdac_out(addr & 3, val, svga->ramdac, svga);
|
||||
else {
|
||||
switch (addr & 3) {
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
@@ -3294,7 +3338,8 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
mach64_log("Ext RAMDAC TYPE write=%x, bit set=%03x.\n", addr & 0x3ff, mach64->dac_cntl & 0x100);
|
||||
if ((addr & 3) >= 1) {
|
||||
svga_set_ramdac_type(svga, !!(mach64->dac_cntl & 0x100));
|
||||
ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100));
|
||||
if (mach64->type == MACH64_GX)
|
||||
ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100));
|
||||
}
|
||||
i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000));
|
||||
break;
|
||||
@@ -3306,7 +3351,10 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
WRITE8(addr, mach64->gen_test_cntl, val);
|
||||
ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
|
||||
mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
|
||||
svga->dac_hwcursor.ena = mach64->gen_test_cntl & 0x80;
|
||||
if (mach64->type == MACH64_GX)
|
||||
svga->dac_hwcursor.ena = !!(mach64->gen_test_cntl & 0x80);
|
||||
else
|
||||
svga->hwcursor.ena = !!(mach64->gen_test_cntl & 0x80);
|
||||
break;
|
||||
|
||||
case 0xdc:
|
||||
@@ -3371,6 +3419,7 @@ uint8_t
|
||||
mach64_ext_inb(uint16_t port, void *priv)
|
||||
{
|
||||
mach64_t *mach64 = (mach64_t *) priv;
|
||||
svga_t *svga = &mach64->svga;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
@@ -3384,6 +3433,12 @@ mach64_ext_inb(uint16_t port, void *priv)
|
||||
case 0x7eef:
|
||||
ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), priv);
|
||||
break;
|
||||
case 0x06ec:
|
||||
case 0x06ed:
|
||||
case 0x06ee:
|
||||
case 0x06ef:
|
||||
ret = mach64_ext_readb(0x400 | 0x04 | (port & 3), priv);
|
||||
break;
|
||||
case 0x0aec:
|
||||
case 0x0aed:
|
||||
case 0x0aee:
|
||||
@@ -3519,8 +3574,22 @@ mach64_ext_inb(uint16_t port, void *priv)
|
||||
case 0x5eef:
|
||||
if (mach64->type == MACH64_GX)
|
||||
ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga);
|
||||
else
|
||||
ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga);
|
||||
else {
|
||||
switch (port & 3) {
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x62ec:
|
||||
@@ -3617,6 +3686,12 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
|
||||
case 0x7eef:
|
||||
mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, priv);
|
||||
break;
|
||||
case 0x06ec:
|
||||
case 0x06ed:
|
||||
case 0x06ee:
|
||||
case 0x06ef:
|
||||
mach64_ext_writeb(0x400 | 0x04 | (port & 3), val, priv);
|
||||
break;
|
||||
case 0x0aec:
|
||||
case 0x0aed:
|
||||
case 0x0aee:
|
||||
@@ -3745,8 +3820,22 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
|
||||
case 0x5eef:
|
||||
if (mach64->type == MACH64_GX)
|
||||
ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga);
|
||||
else
|
||||
ati68860_ramdac_out(port & 3, val, svga->ramdac, svga);
|
||||
else {
|
||||
switch (port & 3) {
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x62ec:
|
||||
@@ -3905,6 +3994,63 @@ mach64_readl(uint32_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
mach64_int_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
const mach64_t *mach64 = (mach64_t *) svga->priv;
|
||||
int comb;
|
||||
int offset;
|
||||
int x_pos;
|
||||
int y_pos;
|
||||
int shift = 0;
|
||||
uint16_t dat;
|
||||
uint32_t col0 = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff);
|
||||
uint32_t col1 = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff);
|
||||
uint32_t *p;
|
||||
|
||||
offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
if (svga->packed_4bpp)
|
||||
shift = 1;
|
||||
|
||||
for (int x = 0; x < svga->hwcursor_latch.cur_xsize; x += (8 >> shift)) {
|
||||
if (shift) {
|
||||
dat = svga->vram[(svga->hwcursor_latch.addr) & svga->vram_mask] & 0x0f;
|
||||
dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 4);
|
||||
dat |= (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_mask] << 8);
|
||||
dat |= (svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_mask] << 12);
|
||||
} else {
|
||||
dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask];
|
||||
dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 8);
|
||||
}
|
||||
for (int xx = 0; xx < (8 >> shift); xx++) {
|
||||
comb = (dat >> (xx << 1)) & 0x03;
|
||||
|
||||
y_pos = displine;
|
||||
x_pos = offset + svga->x_add;
|
||||
p = buffer32->line[y_pos];
|
||||
|
||||
if (offset >= svga->hwcursor_latch.x) {
|
||||
switch (comb) {
|
||||
case 0:
|
||||
p[x_pos] = col0;
|
||||
break;
|
||||
case 1:
|
||||
p[x_pos] = col1;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] ^= 0xffffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
svga->hwcursor_latch.addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
#define CLAMP(x) \
|
||||
do { \
|
||||
if ((x) & ~0xff) \
|
||||
@@ -4550,15 +4696,22 @@ mach64_common_init(const device_t *info)
|
||||
|
||||
svga = &mach64->svga;
|
||||
|
||||
mach64->type = info->local & 0xff;
|
||||
mach64->vram_size = device_get_config_int("memory");
|
||||
mach64->vram_mask = (mach64->vram_size << 20) - 1;
|
||||
|
||||
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
||||
mach64_recalctimings,
|
||||
mach64_in, mach64_out,
|
||||
NULL,
|
||||
mach64_overlay_draw);
|
||||
svga->dac_hwcursor.cur_ysize = 64;
|
||||
if (mach64->type > MACH64_GX)
|
||||
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
||||
mach64_recalctimings,
|
||||
mach64_in, mach64_out,
|
||||
mach64_int_hwcursor_draw,
|
||||
mach64_overlay_draw);
|
||||
else
|
||||
svga_init(info, svga, mach64, mach64->vram_size << 20,
|
||||
mach64_recalctimings,
|
||||
mach64_in, mach64_out,
|
||||
NULL,
|
||||
mach64_overlay_draw);
|
||||
|
||||
mem_mapping_add(&mach64->linear_mapping, 0, 0, mach64_read_linear, mach64_readw_linear, mach64_readl_linear, mach64_write_linear, mach64_writew_linear, mach64_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga);
|
||||
mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64);
|
||||
@@ -4576,9 +4729,6 @@ mach64_common_init(const device_t *info)
|
||||
mach64->pci_regs[0x32] = 0x0c;
|
||||
mach64->pci_regs[0x33] = 0x00;
|
||||
|
||||
svga->ramdac = device_add(&ati68860_ramdac_device);
|
||||
svga->dac_hwcursor_draw = ati68860_hwcursor_draw;
|
||||
|
||||
svga->clock_gen = device_add(&ics2595_device);
|
||||
|
||||
mach64->dst_cntl = 3;
|
||||
@@ -4598,6 +4748,13 @@ static void *
|
||||
mach64gx_init(const device_t *info)
|
||||
{
|
||||
mach64_t *mach64 = mach64_common_init(info);
|
||||
svga_t *svga = &mach64->svga;
|
||||
|
||||
svga->ramdac = device_add(&ati68860_ramdac_device);
|
||||
svga->dac_hwcursor_draw = ati68860_hwcursor_draw;
|
||||
|
||||
svga->dac_hwcursor.cur_ysize = 64;
|
||||
svga->dac_hwcursor.cur_xsize = 64;
|
||||
|
||||
if (info->flags & DEVICE_ISA16)
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa);
|
||||
@@ -4606,12 +4763,11 @@ mach64gx_init(const device_t *info)
|
||||
else
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb);
|
||||
|
||||
mach64->type = MACH64_GX;
|
||||
mach64->pci = !!(info->flags & DEVICE_PCI);
|
||||
mach64->pci_id = 'X' | ('G' << 8);
|
||||
mach64->config_chip_id = 0x000000d7;
|
||||
mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
|
||||
mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/
|
||||
mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI 68860, 256Kx16 DRAM*/
|
||||
if (info->flags & DEVICE_PCI) {
|
||||
mach64->config_stat0 |= 7; /*PCI, 256Kx16 DRAM*/
|
||||
ati_eeprom_load(&mach64->eeprom, "mach64_pci.nvr", 1);
|
||||
@@ -4635,9 +4791,13 @@ mach64vt2_init(const device_t *info)
|
||||
mach64_t *mach64 = mach64_common_init(info);
|
||||
svga_t *svga = &mach64->svga;
|
||||
|
||||
svga->dac_hwcursor_draw = NULL;
|
||||
|
||||
svga->hwcursor.cur_ysize = 64;
|
||||
svga->hwcursor.cur_xsize = 64;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci);
|
||||
|
||||
mach64->type = MACH64_VT2;
|
||||
mach64->pci = 1;
|
||||
mach64->pci_id = 0x5654;
|
||||
mach64->config_chip_id = 0x40005654;
|
||||
@@ -4757,7 +4917,7 @@ const device_t mach64gx_isa_device = {
|
||||
.name = "ATI Mach64GX ISA",
|
||||
.internal_name = "mach64gx_isa",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0,
|
||||
.local = MACH64_GX,
|
||||
.init = mach64gx_init,
|
||||
.close = mach64_close,
|
||||
.reset = NULL,
|
||||
@@ -4771,7 +4931,7 @@ const device_t mach64gx_vlb_device = {
|
||||
.name = "ATI Mach64GX VLB",
|
||||
.internal_name = "mach64gx_vlb",
|
||||
.flags = DEVICE_VLB,
|
||||
.local = 0,
|
||||
.local = MACH64_GX,
|
||||
.init = mach64gx_init,
|
||||
.close = mach64_close,
|
||||
.reset = NULL,
|
||||
@@ -4785,7 +4945,7 @@ const device_t mach64gx_pci_device = {
|
||||
.name = "ATI Mach64GX PCI",
|
||||
.internal_name = "mach64gx_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.local = MACH64_GX,
|
||||
.init = mach64gx_init,
|
||||
.close = mach64_close,
|
||||
.reset = NULL,
|
||||
@@ -4799,7 +4959,7 @@ const device_t mach64vt2_device = {
|
||||
.name = "ATI Mach64VT2",
|
||||
.internal_name = "mach64vt2",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.local = MACH64_VT2,
|
||||
.init = mach64vt2_init,
|
||||
.close = mach64_close,
|
||||
.reset = NULL,
|
||||
|
||||
@@ -817,6 +817,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
||||
dev->accel.dy |= ~0x5ff;
|
||||
|
||||
/*Destination Width*/
|
||||
mach->accel.dx_first_row_start = dev->accel.cur_x;
|
||||
if (dev->accel.cur_x >= 0x600)
|
||||
mach->accel.dx_first_row_start |= ~0x5ff;
|
||||
|
||||
mach->accel.dx_start = mach->accel.dest_x_start;
|
||||
if (mach->accel.dest_x_start >= 0x600)
|
||||
mach->accel.dx_start |= ~0x5ff;
|
||||
@@ -831,16 +835,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
||||
} else if (mach->accel.dx_end < mach->accel.dx_start) {
|
||||
mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end);
|
||||
mach->accel.stepx = -1;
|
||||
if (dev->accel.dx > 0)
|
||||
dev->accel.dx--;
|
||||
mach_log("BitBLT: Dst Negative X, dxstart = %d, end = %d, width = %d, dx = %d, dpconfig = %04x.\n",
|
||||
mach->accel.dest_x_start, mach->accel.dest_x_end, mach->accel.width, dev->accel.dx,
|
||||
mach->accel.dp_config);
|
||||
} else {
|
||||
mach->accel.stepx = 1;
|
||||
mach->accel.width = 0;
|
||||
mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n",
|
||||
mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start);
|
||||
}
|
||||
|
||||
dev->accel.sx = 0;
|
||||
@@ -869,6 +866,24 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
||||
if (mach->accel.dp_config == 0x4011)
|
||||
mach->accel.height++;
|
||||
|
||||
if (mach->accel.height == 1) {
|
||||
if (mach->accel.dx_end > mach->accel.dx_first_row_start) {
|
||||
mach->accel.width = (mach->accel.dx_end - mach->accel.dx_first_row_start);
|
||||
mach->accel.stepx = 1;
|
||||
} else if (mach->accel.dx_end < mach->accel.dx_first_row_start) {
|
||||
mach->accel.width = (mach->accel.dx_first_row_start - mach->accel.dx_end);
|
||||
mach->accel.stepx = -1;
|
||||
} else {
|
||||
mach->accel.stepx = 1;
|
||||
mach->accel.width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mach->accel.stepx == -1) {
|
||||
if (dev->accel.dx > 0)
|
||||
dev->accel.dx--;
|
||||
}
|
||||
|
||||
dev->accel.sy = 0;
|
||||
dev->accel.dest = mach->accel.dst_ge_offset + (dev->accel.dy * mach->accel.dst_pitch);
|
||||
|
||||
@@ -2461,7 +2476,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -2604,7 +2619,7 @@ ati_render_24bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -2613,38 +2628,38 @@ ati_render_24bpp(svga_t *svga)
|
||||
|
||||
if (mach->accel.ext_ge_config & 0x400) { /*BGR, Blue-(23:16), Green-(15:8), Red-(7:0)*/
|
||||
for (int x = 0; x <= dev->h_disp; x += 4) {
|
||||
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]);
|
||||
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]);
|
||||
p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]);
|
||||
p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]);
|
||||
p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||
|
||||
dev->ma += 12;
|
||||
dev->memaddr += 12;
|
||||
}
|
||||
} else { /*RGB, Red-(23:16), Green-(15:8), Blue-(7:0)*/
|
||||
for (int x = 0; x <= dev->h_disp; x += 4) {
|
||||
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]);
|
||||
p[x] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]);
|
||||
p[x + 1] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]);
|
||||
p[x + 2] = dat & 0xffffff;
|
||||
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]);
|
||||
p[x + 3] = dat & 0xffffff;
|
||||
|
||||
dev->ma += 12;
|
||||
dev->memaddr += 12;
|
||||
}
|
||||
}
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2660,7 +2675,7 @@ ati_render_32bpp(svga_t *svga)
|
||||
if ((dev->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || dev->changedvram[(dev->ma >> 12) + 2] || svga->fullchange) {
|
||||
if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || dev->changedvram[(dev->memaddr >> 12) + 2] || svga->fullchange) {
|
||||
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (dev->firstline_draw == 2000)
|
||||
@@ -2669,17 +2684,17 @@ ati_render_32bpp(svga_t *svga)
|
||||
|
||||
if (mach->accel.ext_ge_config & 0x400) { /*BGR, Blue-(23:16), Green-(15:8), Red-(7:0)*/
|
||||
for (x = 0; x <= dev->h_disp; x++) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]);
|
||||
*p++ = ((dat & 0x00ff0000) >> 16) | (dat & 0x0000ff00) | ((dat & 0x000000ff) << 16);
|
||||
}
|
||||
} else { /*RGB, Red-(31:24), Green-(23:16), Blue-(15:8)*/
|
||||
for (x = 0; x <= dev->h_disp; x++) {
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
|
||||
dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]);
|
||||
*p++ = ((dat & 0xffffff00) >> 8);
|
||||
}
|
||||
}
|
||||
dev->ma += (x * 4);
|
||||
dev->ma &= dev->vram_mask;
|
||||
dev->memaddr += (x * 4);
|
||||
dev->memaddr &= dev->vram_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2847,17 +2862,17 @@ mach_recalctimings(svga_t *svga)
|
||||
|
||||
if (ATI_MACH32) {
|
||||
if (mach->regs[0xad] & 0x04)
|
||||
svga->ma_latch |= 0x40000;
|
||||
svga->memaddr_latch |= 0x40000;
|
||||
|
||||
if (mach->regs[0xad] & 0x08)
|
||||
svga->ma_latch |= 0x80000;
|
||||
svga->memaddr_latch |= 0x80000;
|
||||
}
|
||||
|
||||
if (mach->regs[0xa3] & 0x10)
|
||||
svga->ma_latch |= 0x10000;
|
||||
svga->memaddr_latch |= 0x10000;
|
||||
|
||||
if (mach->regs[0xb0] & 0x40)
|
||||
svga->ma_latch |= 0x20000;
|
||||
svga->memaddr_latch |= 0x20000;
|
||||
|
||||
if ((mach->regs[0xb6] & 0x18) >= 0x10) {
|
||||
svga->hdisp <<= 1;
|
||||
@@ -2886,7 +2901,7 @@ mach_recalctimings(svga_t *svga)
|
||||
|
||||
mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, svga->hdisp);
|
||||
if (dev->on) {
|
||||
dev->ma_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/
|
||||
dev->memaddr_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/
|
||||
dev->interlace = !!(dev->disp_cntl & 0x10);
|
||||
dev->pitch = dev->ext_pitch;
|
||||
dev->rowoffset = dev->ext_crt_pitch;
|
||||
@@ -3085,7 +3100,7 @@ mach_recalctimings(svga_t *svga)
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if (!svga->packed_4bpp) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
@@ -3297,7 +3312,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 {
|
||||
@@ -3972,7 +3987,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
|
||||
break;
|
||||
|
||||
case 0x92ee:
|
||||
mach_log("Write port 92ee, malatch=%08x.\n", svga->ma_latch);
|
||||
mach_log("Write port 92ee, malatch=%08x.\n", svga->memaddr_latch);
|
||||
break;
|
||||
|
||||
case 0x96ee:
|
||||
@@ -4227,7 +4242,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
|
||||
break;
|
||||
|
||||
default:
|
||||
mach_log("Unknown or reserved write to %04x, val=%04x, len=%d, latch=%08x.\n", port, val, len, svga->ma_latch);
|
||||
mach_log("Unknown or reserved write to %04x, val=%04x, len=%d, latch=%08x.\n", port, val, len, svga->memaddr_latch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6475,6 +6490,7 @@ ati8514_io_set(svga_t *svga)
|
||||
io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||
io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||
io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||
io_sethandler(0xfaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||
io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
|
||||
}
|
||||
|
||||
@@ -7409,7 +7425,7 @@ const device_t mach8_vga_isa_device = {
|
||||
.name = "ATI Mach8 (ATI Graphics Ultra) (ISA)",
|
||||
.internal_name = "mach8_vga_isa",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.local = ATI_38800_TYPE,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
@@ -7423,7 +7439,7 @@ const device_t mach32_isa_device = {
|
||||
.name = "ATI Mach32 (ISA)",
|
||||
.internal_name = "mach32_isa",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 2,
|
||||
.local = ATI_68800_TYPE,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
@@ -7437,7 +7453,7 @@ const device_t mach32_vlb_device = {
|
||||
.name = "ATI Mach32 (VLB)",
|
||||
.internal_name = "mach32_vlb",
|
||||
.flags = DEVICE_VLB,
|
||||
.local = 2,
|
||||
.local = ATI_68800_TYPE,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
@@ -7451,7 +7467,7 @@ const device_t mach32_mca_device = {
|
||||
.name = "ATI Mach32 (MCA)",
|
||||
.internal_name = "mach32_mca",
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 2,
|
||||
.local = ATI_68800_TYPE,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
@@ -7465,7 +7481,7 @@ const device_t mach32_pci_device = {
|
||||
.name = "ATI Mach32 (PCI)",
|
||||
.internal_name = "mach32_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 2,
|
||||
.local = ATI_68800_TYPE,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
@@ -7479,7 +7495,7 @@ const device_t mach32_onboard_pci_device = {
|
||||
.name = "ATI Mach32 (PCI) On-Board",
|
||||
.internal_name = "mach32_pci_onboard",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 2 | 0x100,
|
||||
.local = ATI_68800_TYPE | 0x100,
|
||||
.init = mach8_init,
|
||||
.close = mach_close,
|
||||
.reset = mach_reset,
|
||||
|
||||
@@ -336,13 +336,13 @@ bochs_vbe_recalctimings(svga_t* svga)
|
||||
|
||||
if (svga->bpp == 4) {
|
||||
svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3;
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3);
|
||||
|
||||
svga->fullchange = 3;
|
||||
} else {
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
|
||||
svga->fullchange = 3;
|
||||
}
|
||||
@@ -470,11 +470,11 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv)
|
||||
svga_t *svga = &dev->svga;
|
||||
if (svga->bpp == 4) {
|
||||
svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3;
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3);
|
||||
} else {
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
|
||||
}
|
||||
|
||||
@@ -575,7 +575,7 @@ bochs_vbe_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
|
||||
@@ -73,10 +73,10 @@ void cga_recalctimings(cga_t *cga);
|
||||
static void
|
||||
cga_update_latch(cga_t *cga)
|
||||
{
|
||||
uint32_t lp_latch = cga->displine * cga->crtc[1];
|
||||
uint32_t lp_latch = cga->displine * cga->crtc[CGA_CRTC_HDISP];
|
||||
|
||||
cga->crtc[0x10] = (lp_latch >> 8) & 0x3f;
|
||||
cga->crtc[0x11] = lp_latch & 0xff;
|
||||
cga->crtc[CGA_CRTC_LIGHT_PEN_ADDR_HIGH] = (lp_latch >> 8) & 0x3f;
|
||||
cga->crtc[CGA_CRTC_LIGHT_PEN_ADDR_LOW] = lp_latch & 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -89,20 +89,22 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
case CGA_REGISTER_CRTC_INDEX:
|
||||
cga->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
case CGA_REGISTER_CRTC_DATA:
|
||||
old = cga->crtc[cga->crtcreg];
|
||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||
if (old != val) {
|
||||
// Recalc the timings if we are writing any invalid CRTC register or a valid CRTC register
|
||||
// except the CURSOR and LIGHT PEN registers
|
||||
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x11)) {
|
||||
cga->fullchange = changeframecount;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
case CGA_REGISTER_MODE_CONTROL:
|
||||
old = cga->cgamode;
|
||||
cga->cgamode = val;
|
||||
|
||||
@@ -113,18 +115,18 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
case CGA_REGISTER_COLOR_SELECT:
|
||||
old = cga->cgacol;
|
||||
cga->cgacol = val;
|
||||
if (old ^ val)
|
||||
cga_recalctimings(cga);
|
||||
return;
|
||||
|
||||
case 0x3DB:
|
||||
case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH:
|
||||
if (cga->lp_strobe == 1)
|
||||
cga->lp_strobe = 0;
|
||||
return;
|
||||
case 0x3DC:
|
||||
case CGA_REGISTER_SET_LIGHT_PEN_LATCH:
|
||||
if (cga->lp_strobe == 0) {
|
||||
cga->lp_strobe = 1;
|
||||
cga_update_latch(cga);
|
||||
@@ -146,21 +148,20 @@ cga_in(uint16_t addr, void *priv)
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
case CGA_REGISTER_CRTC_INDEX:
|
||||
ret = cga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
case CGA_REGISTER_CRTC_DATA:
|
||||
ret = cga->crtc[cga->crtcreg];
|
||||
break;
|
||||
case 0x3DA:
|
||||
case CGA_REGISTER_STATUS:
|
||||
ret = cga->cgastat;
|
||||
break;
|
||||
|
||||
case 0x3DB:
|
||||
case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH:
|
||||
if (cga->lp_strobe == 1)
|
||||
cga->lp_strobe = 0;
|
||||
break;
|
||||
case 0x3DC:
|
||||
case CGA_REGISTER_SET_LIGHT_PEN_LATCH:
|
||||
if (cga->lp_strobe == 0) {
|
||||
cga->lp_strobe = 1;
|
||||
cga_update_latch(cga);
|
||||
@@ -235,12 +236,12 @@ cga_recalctimings(cga_t *cga)
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
|
||||
if (cga->cgamode & 1) {
|
||||
disptime = (double) (cga->crtc[0] + 1);
|
||||
_dispontime = (double) cga->crtc[1];
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
disptime = (double) (cga->crtc[CGA_CRTC_HTOTAL] + 1);
|
||||
_dispontime = (double) cga->crtc[CGA_CRTC_HDISP];
|
||||
} else {
|
||||
disptime = (double) ((cga->crtc[0] + 1) << 1);
|
||||
_dispontime = (double) (cga->crtc[1] << 1);
|
||||
disptime = (double) ((cga->crtc[CGA_CRTC_HTOTAL] + 1) << 1);
|
||||
_dispontime = (double) (cga->crtc[CGA_CRTC_HDISP] << 1);
|
||||
}
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime = _dispontime * CGACONST;
|
||||
@@ -252,95 +253,97 @@ cga_recalctimings(cga_t *cga)
|
||||
static void
|
||||
cga_render(cga_t *cga, int line)
|
||||
{
|
||||
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int column;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
|
||||
if ((cga->cgamode & 0x12) == 0x12) {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
buffer32->line[line][c] = 0;
|
||||
if (cga->cgamode & 1)
|
||||
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = 0;
|
||||
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
|
||||
|
||||
if (((cga->cgamode & highres_graphics_flag) == highres_graphics_flag)) {
|
||||
for (column = 0; column < 8; ++column) {
|
||||
buffer32->line[line][column] = 0;
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = 0;
|
||||
else
|
||||
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0;
|
||||
buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
buffer32->line[line][c] = (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1)
|
||||
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||
for (column = 0; column < 8; ++column) {
|
||||
buffer32->line[line][column] = (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||
else
|
||||
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
|
||||
buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 4) + 8] = (cga->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
if (cga->cgamode & 1) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[line][(x << 3) + c + 8]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
for (column = 0; column < 8; column++) {
|
||||
buffer32->line[line][(x << 3) + column + 8]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[line][(x << 3) + c + 8]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
for (column = 0; column < 8; column++) {
|
||||
buffer32->line[line][(x << 3) + column + 8]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
cga->ma++;
|
||||
cga->memaddr++;
|
||||
}
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
chr = cga->vram[(cga->ma << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
chr = cga->vram[(cga->memaddr << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->memaddr << 1) + 1) & 0x3fff];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80))
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
cga->ma++;
|
||||
cga->memaddr++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[line][(x << 4) + (c << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (c << 1) + 9]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
for (column = 0; column < 8; column++) {
|
||||
buffer32->line[line][(x << 4) + (column << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (column << 1) + 9]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[line][(x << 4) + (c << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (c << 1) + 9]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
for (column = 0; column < 8; column++) {
|
||||
buffer32->line[line][(x << 4) + (column << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (column << 1) + 9]
|
||||
= cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
cols[0] = (cga->cgacol & 15) | 16;
|
||||
col = (cga->cgacol & 16) ? 24 : 16;
|
||||
if (cga->cgamode & 4) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_BW) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 7; /* White */
|
||||
@@ -353,16 +356,16 @@ cga_render(cga_t *cga, int line)
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 6; /* Yellow */
|
||||
}
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
|
||||
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)
|
||||
dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) |
|
||||
cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[line][(x << 4) + (c << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (c << 1) + 9]
|
||||
cga->memaddr++;
|
||||
for (column = 0; column < 8; column++) {
|
||||
buffer32->line[line][(x << 4) + (column << 1) + 8]
|
||||
= buffer32->line[line][(x << 4) + (column << 1) + 9]
|
||||
= cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
@@ -370,15 +373,15 @@ cga_render(cga_t *cga, int line)
|
||||
} else {
|
||||
cols[0] = 0;
|
||||
cols[1] = (cga->cgacol & 15) + 16;
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
|
||||
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)
|
||||
dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) |
|
||||
cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[line][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
cga->memaddr++;
|
||||
for (column = 0; column < 16; column++) {
|
||||
buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
@@ -388,12 +391,14 @@ cga_render(cga_t *cga, int line)
|
||||
static void
|
||||
cga_render_blank(cga_t *cga, int line)
|
||||
{
|
||||
int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
|
||||
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
|
||||
|
||||
if (cga->cgamode & 1)
|
||||
hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col);
|
||||
int col = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15) + 16;
|
||||
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 3) + 16, col);
|
||||
else
|
||||
hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col);
|
||||
hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 4) + 16, col);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -401,14 +406,15 @@ cga_render_process(cga_t *cga, int line)
|
||||
{
|
||||
int x;
|
||||
uint8_t border;
|
||||
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
|
||||
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
if (cga->composite) {
|
||||
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
|
||||
border = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15);
|
||||
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]);
|
||||
} else
|
||||
@@ -513,7 +519,7 @@ cga_poll(void *priv)
|
||||
{
|
||||
cga_t *cga = (cga_t *) priv;
|
||||
int x;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int oldvc;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
@@ -523,9 +529,9 @@ cga_poll(void *priv)
|
||||
timer_advance_u64(&cga->timer, cga->dispofftime);
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
scanline_old = cga->scanline;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
cga->scanline = ((cga->scanline << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon) {
|
||||
if (cga->displine < cga->firstline) {
|
||||
cga->firstline = cga->displine;
|
||||
@@ -541,9 +547,9 @@ cga_poll(void *priv)
|
||||
cga_render(cga, cga->displine);
|
||||
break;
|
||||
case DOUBLE_SIMPLE:
|
||||
old_ma = cga->ma;
|
||||
old_ma = cga->memaddr;
|
||||
cga_render(cga, cga->displine << 1);
|
||||
cga->ma = old_ma;
|
||||
cga->memaddr = old_ma;
|
||||
cga_render(cga, (cga->displine << 1) + 1);
|
||||
break;
|
||||
}
|
||||
@@ -572,8 +578,8 @@ cga_poll(void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->scanline = scanline_old;
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->scanline)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
@@ -586,41 +592,41 @@ cga_poll(void *priv)
|
||||
if (!cga->vsynctime)
|
||||
cga->cgastat &= ~8;
|
||||
}
|
||||
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 &&
|
||||
cga->sc == ((cga->crtc[11] & 31) >> 1))) {
|
||||
cga->con = 0;
|
||||
cga->coff = 1;
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 &&
|
||||
cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
cga->cursorvisible = 0;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
if (cga->vadj) {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
cga->scanline = 0;
|
||||
}
|
||||
} else if (cga->sc == cga->crtc[9]) {
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
} else if (cga->scanline == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) {
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
cga->scanline = 0;
|
||||
oldvc = cga->vc;
|
||||
cga->vc++;
|
||||
cga->vc &= 127;
|
||||
|
||||
if (cga->vc == cga->crtc[6])
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VDISP])
|
||||
cga->cgadispon = 0;
|
||||
|
||||
if (oldvc == cga->crtc[4]) {
|
||||
if (oldvc == cga->crtc[CGA_CRTC_VTOTAL]) {
|
||||
cga->vc = 0;
|
||||
cga->vadj = cga->crtc[5];
|
||||
cga->vadj = cga->crtc[CGA_CRTC_VTOTAL_ADJUST];
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (cga->crtc[10] & 0x60) {
|
||||
|
||||
switch (cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) {
|
||||
case 0x20:
|
||||
cga->cursoron = 0;
|
||||
break;
|
||||
@@ -633,15 +639,15 @@ cga_poll(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (cga->vc == cga->crtc[7]) {
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC]) {
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = 16;
|
||||
if (cga->crtc[7]) {
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
if (cga->crtc[CGA_CRTC_VSYNC]) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
cga->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
@@ -657,7 +663,7 @@ cga_poll(void *priv)
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((cga->cgamode & 8) && ((xs_temp != xsize) ||
|
||||
if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) ||
|
||||
(ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
@@ -691,15 +697,15 @@ cga_poll(void *priv)
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (cga->cgamode & 1) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
@@ -711,18 +717,18 @@ cga_poll(void *priv)
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
}
|
||||
if (cga->cgadispon)
|
||||
cga->cgastat &= ~1;
|
||||
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 &&
|
||||
cga->sc == ((cga->crtc[10] & 31) >> 1)))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1)) {
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff];
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 &&
|
||||
cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
cga->cursorvisible = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
for (x = 0; x < (cga->crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[((cga->memaddr << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,19 +37,19 @@
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
/* Bits in the colorplus control register: */
|
||||
#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */
|
||||
#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */
|
||||
#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */
|
||||
#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */
|
||||
#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */
|
||||
#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */
|
||||
#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */
|
||||
#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */
|
||||
|
||||
/* Bits in the CGA graphics mode register */
|
||||
#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
// Plantronics specific registers
|
||||
#define COLORPLUS_CONTROL 0x3DD
|
||||
|
||||
video_timings_t timing_colorplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
@@ -60,7 +60,7 @@ colorplus_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *) priv;
|
||||
|
||||
if (addr == 0x3DD) {
|
||||
if (addr == COLORPLUS_CONTROL) {
|
||||
colorplus->control = val & 0x70;
|
||||
} else {
|
||||
cga_out(addr, val, &colorplus->cga);
|
||||
@@ -80,7 +80,7 @@ colorplus_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *) priv;
|
||||
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
addr ^= 0x4000;
|
||||
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
|
||||
addr &= 0x3FFF;
|
||||
@@ -99,7 +99,7 @@ colorplus_read(uint32_t addr, void *priv)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *) priv;
|
||||
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
addr ^= 0x4000;
|
||||
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
|
||||
addr &= 0x3FFF;
|
||||
@@ -130,7 +130,7 @@ colorplus_poll(void *priv)
|
||||
uint16_t dat1;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
static const int cols16[16] = { 0x10, 0x12, 0x14, 0x16,
|
||||
0x18, 0x1A, 0x1C, 0x1E,
|
||||
0x11, 0x13, 0x15, 0x17,
|
||||
@@ -140,7 +140,7 @@ colorplus_poll(void *priv)
|
||||
|
||||
/* If one of the extra modes is not selected, drop down to the CGA
|
||||
* drawing code. */
|
||||
if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) {
|
||||
if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS))) {
|
||||
cga_poll(&colorplus->cga);
|
||||
return;
|
||||
}
|
||||
@@ -149,9 +149,9 @@ colorplus_poll(void *priv)
|
||||
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime);
|
||||
colorplus->cga.cgastat |= 1;
|
||||
colorplus->cga.linepos = 1;
|
||||
oldsc = colorplus->cga.sc;
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3)
|
||||
colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7;
|
||||
scanline_old = colorplus->cga.scanline;
|
||||
if ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
colorplus->cga.scanline = ((colorplus->cga.scanline << 1) + colorplus->cga.oddeven) & 7;
|
||||
if (colorplus->cga.cgadispon) {
|
||||
if (colorplus->cga.displine < colorplus->cga.firstline) {
|
||||
colorplus->cga.firstline = colorplus->cga.displine;
|
||||
@@ -160,13 +160,13 @@ colorplus_poll(void *priv)
|
||||
colorplus->cga.lastline = colorplus->cga.displine;
|
||||
/* Left / right border */
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16;
|
||||
buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16;
|
||||
}
|
||||
if (colorplus->control & COLORPLUS_320x200_MODE) {
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (x = 0; x < colorplus->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1];
|
||||
colorplus->cga.memaddr++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)];
|
||||
dat0 <<= 2;
|
||||
@@ -176,7 +176,7 @@ colorplus_poll(void *priv)
|
||||
} else if (colorplus->control & COLORPLUS_640x200_MODE) {
|
||||
cols[0] = (colorplus->cga.cgacol & 15) | 16;
|
||||
col = (colorplus->cga.cgacol & 16) ? 24 : 16;
|
||||
if (colorplus->cga.cgamode & 4) {
|
||||
if (colorplus->cga.cgamode & CGA_MODE_FLAG_BW) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
@@ -189,10 +189,10 @@ colorplus_poll(void *priv)
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (x = 0; x < colorplus->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1];
|
||||
colorplus->cga.memaddr++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] = cols[(dat0 >> 15) | ((dat1 >> 15) << 1)];
|
||||
dat0 <<= 1;
|
||||
@@ -203,18 +203,18 @@ colorplus_poll(void *priv)
|
||||
} else /* Top / bottom border */
|
||||
{
|
||||
cols[0] = (colorplus->cga.cgacol & 15) + 16;
|
||||
hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
if (colorplus->cga.composite)
|
||||
Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]);
|
||||
else
|
||||
video_process_8(x, colorplus->cga.displine);
|
||||
|
||||
colorplus->cga.sc = oldsc;
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc)
|
||||
colorplus->cga.scanline = scanline_old;
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VSYNC] && !colorplus->cga.scanline)
|
||||
colorplus->cga.cgastat |= 8;
|
||||
colorplus->cga.displine++;
|
||||
if (colorplus->cga.displine >= 360)
|
||||
@@ -227,54 +227,54 @@ colorplus_poll(void *priv)
|
||||
if (!colorplus->cga.vsynctime)
|
||||
colorplus->cga.cgastat &= ~8;
|
||||
}
|
||||
if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) {
|
||||
colorplus->cga.con = 0;
|
||||
colorplus->cga.coff = 1;
|
||||
if (colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_CURSOR_END] & 31)
|
||||
|| ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == ((colorplus->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
colorplus->cga.cursorvisible = 0;
|
||||
}
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1))
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
if ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
colorplus->cga.memaddr_backup = colorplus->cga.memaddr;
|
||||
if (colorplus->cga.vadj) {
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
colorplus->cga.scanline++;
|
||||
colorplus->cga.scanline &= 31;
|
||||
colorplus->cga.memaddr = colorplus->cga.memaddr_backup;
|
||||
colorplus->cga.vadj--;
|
||||
if (!colorplus->cga.vadj) {
|
||||
colorplus->cga.cgadispon = 1;
|
||||
colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
colorplus->cga.sc = 0;
|
||||
colorplus->cga.memaddr = colorplus->cga.memaddr_backup = (colorplus->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (colorplus->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
colorplus->cga.scanline = 0;
|
||||
}
|
||||
} else if (colorplus->cga.sc == colorplus->cga.crtc[9]) {
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
colorplus->cga.sc = 0;
|
||||
} else if (colorplus->cga.scanline == colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) {
|
||||
colorplus->cga.memaddr_backup = colorplus->cga.memaddr;
|
||||
colorplus->cga.scanline = 0;
|
||||
oldvc = colorplus->cga.vc;
|
||||
colorplus->cga.vc++;
|
||||
colorplus->cga.vc &= 127;
|
||||
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[6])
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VDISP])
|
||||
colorplus->cga.cgadispon = 0;
|
||||
|
||||
if (oldvc == colorplus->cga.crtc[4]) {
|
||||
if (oldvc == colorplus->cga.crtc[CGA_CRTC_VTOTAL]) {
|
||||
colorplus->cga.vc = 0;
|
||||
colorplus->cga.vadj = colorplus->cga.crtc[5];
|
||||
colorplus->cga.vadj = colorplus->cga.crtc[CGA_CRTC_VTOTAL_ADJUST];
|
||||
if (!colorplus->cga.vadj)
|
||||
colorplus->cga.cgadispon = 1;
|
||||
if (!colorplus->cga.vadj)
|
||||
colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
if ((colorplus->cga.crtc[10] & 0x60) == 0x20)
|
||||
colorplus->cga.memaddr = colorplus->cga.memaddr_backup = (colorplus->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (colorplus->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
if ((colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
colorplus->cga.cursoron = 0;
|
||||
else
|
||||
colorplus->cga.cursoron = colorplus->cga.cgablink & 8;
|
||||
}
|
||||
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7]) {
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
colorplus->cga.cgadispon = 0;
|
||||
colorplus->cga.displine = 0;
|
||||
colorplus->cga.vsynctime = 16;
|
||||
if (colorplus->cga.crtc[7]) {
|
||||
if (colorplus->cga.cgamode & 1)
|
||||
x = (colorplus->cga.crtc[1] << 3) + 16;
|
||||
if (colorplus->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
if (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
colorplus->cga.lastline++;
|
||||
if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) {
|
||||
xsize = x;
|
||||
@@ -291,15 +291,15 @@ colorplus_poll(void *priv)
|
||||
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (colorplus->cga.cgamode & 1) {
|
||||
if (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_res_y /= colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(colorplus->cga.cgamode & 2)) {
|
||||
} else if (!(colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_res_y /= colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(colorplus->cga.cgamode & 16)) {
|
||||
} else if (!(colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
@@ -312,17 +312,17 @@ colorplus_poll(void *priv)
|
||||
colorplus->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
colorplus->cga.scanline++;
|
||||
colorplus->cga.scanline &= 31;
|
||||
colorplus->cga.memaddr = colorplus->cga.memaddr_backup;
|
||||
}
|
||||
if (colorplus->cga.cgadispon)
|
||||
colorplus->cga.cgastat &= ~1;
|
||||
if (colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))
|
||||
colorplus->cga.con = 1;
|
||||
if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++)
|
||||
colorplus->cga.charbuffer[x] = colorplus->cga.vram[((colorplus->cga.ma << 1) + x) & 0x3fff];
|
||||
if (colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == ((colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
colorplus->cga.cursorvisible = 1;
|
||||
if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
for (x = 0; x < (colorplus->cga.crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
colorplus->cga.charbuffer[x] = colorplus->cga.vram[((colorplus->cga.memaddr << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ update_cga16_color(uint8_t cgamode)
|
||||
int left = (x >> 6) & 15;
|
||||
int rc = right;
|
||||
int lc = left;
|
||||
if ((cgamode & 4) != 0) {
|
||||
if ((cgamode & CGA_MODE_FLAG_BW) != 0) {
|
||||
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
|
||||
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doub
|
||||
for (uint8_t x = 0; x < 5; ++x)
|
||||
OUT(b[x & 3]);
|
||||
|
||||
if ((cgamode & 4) != 0) {
|
||||
if ((cgamode & CGA_MODE_FLAG_BW) != 0) {
|
||||
/* Decode */
|
||||
i = temp + 5;
|
||||
srgb = TempLine;
|
||||
|
||||
511
src/video/vid_cga_compaq.c
Normal file
511
src/video/vid_cga_compaq.c
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* 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 Compaq CGA graphics cards.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: John Elliott, <jce@seasip.info>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2019 John Elliott.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
static uint32_t vflags;
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
#ifdef ENABLE_COMPAQ_CGA_LOG
|
||||
int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG;
|
||||
|
||||
static void
|
||||
compaq_cga_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (compaq_cga_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define compaq_cga_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
compaq_cga_recalctimings(cga_t *dev)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
disptime = dev->crtc[CGA_CRTC_HTOTAL] + 1;
|
||||
|
||||
_dispontime = dev->crtc[CGA_CRTC_HDISP];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
dev->dispontime = (uint64_t) (_dispontime);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_cga_poll(void *priv)
|
||||
{
|
||||
cga_t *dev = (cga_t *) priv;
|
||||
uint16_t cursoraddr = (dev->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (dev->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t border;
|
||||
uint8_t cols[4];
|
||||
int scanline_old;
|
||||
int underline = 0;
|
||||
int blink = 0;
|
||||
|
||||
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
|
||||
|
||||
/* If in graphics mode or character height is not 13, behave as CGA */
|
||||
if ((dev->cgamode & highres_graphics_flag) || (dev->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] != 13)) {
|
||||
overscan_x = overscan_y = 16;
|
||||
cga_poll(dev);
|
||||
return;
|
||||
} else
|
||||
overscan_x = overscan_y = 0;
|
||||
|
||||
/* We are in Compaq 350-line CGA territory */
|
||||
if (!dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->cgastat |= 1;
|
||||
dev->linepos = 1;
|
||||
scanline_old = dev->scanline;
|
||||
if ((dev->crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
dev->scanline = ((dev->scanline << 1) + dev->oddeven) & 7;
|
||||
if (dev->cgadispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
dev->firstline = dev->displine;
|
||||
video_wait_for_buffer();
|
||||
compaq_cga_log("Firstline %i\n", dev->firstline);
|
||||
}
|
||||
dev->lastline = dev->displine;
|
||||
|
||||
cols[0] = (dev->cgacol & 15) + 16;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[dev->displine][c] = cols[0];
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
buffer32->line[dev->displine][c + (dev->crtc[CGA_CRTC_HDISP] << 3) + 8] = cols[0];
|
||||
else
|
||||
buffer32->line[dev->displine][c + (dev->crtc[CGA_CRTC_HDISP] << 4) + 8] = cols[0];
|
||||
}
|
||||
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < dev->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = dev->charbuffer[x << 1];
|
||||
attr = dev->charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((dev->cgablink & 8) && (dev->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (dev->cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
|
||||
if ((dev->scanline == 12) && ((attr & 7) == 1))
|
||||
underline = 1;
|
||||
} else if (dev->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 3) + c + 8] =
|
||||
cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 3) + c + 8] =
|
||||
cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
dev->memaddr++;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < dev->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = dev->vram[(dev->memaddr << 1) & 0x3fff];
|
||||
attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((dev->cgablink & 8) && (dev->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (dev->cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
if (dev->scanline == 12 && (attr & 7) == 1)
|
||||
underline = 1;
|
||||
} else if (dev->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
dev->memaddr++;
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = (dev->cgacol & 15) + 16;
|
||||
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
hline(buffer32, 0, dev->displine, (dev->crtc[CGA_CRTC_HDISP] << 3) + 16, cols[0]);
|
||||
else
|
||||
hline(buffer32, 0, dev->displine, (dev->crtc[CGA_CRTC_HDISP] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (dev->crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (dev->crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
if (dev->composite) {
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
border = 0x00;
|
||||
else
|
||||
border = dev->cgacol & 0x0f;
|
||||
|
||||
if (vflags)
|
||||
Composite_Process(dev->cgamode & 0x7f, border, x >> 2, buffer32->line[dev->displine]);
|
||||
else
|
||||
Composite_Process(dev->cgamode, border, x >> 2, buffer32->line[dev->displine]);
|
||||
} else
|
||||
video_process_8(x, dev->displine);
|
||||
|
||||
dev->scanline = scanline_old;
|
||||
if (dev->vc == dev->crtc[CGA_CRTC_VSYNC] && !dev->scanline)
|
||||
dev->cgastat |= 8;
|
||||
dev->displine++;
|
||||
if (dev->displine >= 500)
|
||||
dev->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&dev->timer, dev->dispontime);
|
||||
dev->linepos = 0;
|
||||
if (dev->vsynctime) {
|
||||
dev->vsynctime--;
|
||||
if (!dev->vsynctime)
|
||||
dev->cgastat &= ~8;
|
||||
}
|
||||
|
||||
if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->cursorvisible = 0;
|
||||
}
|
||||
if ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))
|
||||
dev->memaddr_backup = dev->memaddr;
|
||||
if (dev->vadj) {
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->cgadispon = 1;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->scanline = 0;
|
||||
}
|
||||
} else if (dev->scanline == dev->crtc[9]) {
|
||||
dev->memaddr_backup = dev->memaddr;
|
||||
dev->scanline = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
|
||||
if (dev->vc == dev->crtc[6])
|
||||
dev->cgadispon = 0;
|
||||
|
||||
if (oldvc == dev->crtc[4]) {
|
||||
dev->vc = 0;
|
||||
dev->vadj = dev->crtc[5];
|
||||
|
||||
if (!dev->vadj)
|
||||
dev->cgadispon = 1;
|
||||
|
||||
if (!dev->vadj)
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
|
||||
if ((dev->crtc[10] & 0x60) == 0x20)
|
||||
dev->cursoron = 0;
|
||||
else
|
||||
dev->cursoron = dev->cgablink & 8;
|
||||
}
|
||||
|
||||
if (dev->vc == dev->crtc[7]) {
|
||||
dev->cgadispon = 0;
|
||||
dev->displine = 0;
|
||||
dev->vsynctime = 16;
|
||||
|
||||
if (dev->crtc[7]) {
|
||||
compaq_cga_log("Lastline %i Firstline %i %i\n", dev->lastline,
|
||||
dev->firstline, dev->lastline - dev->firstline);
|
||||
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (dev->crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (dev->crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
dev->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (dev->lastline - dev->firstline);
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((dev->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan)
|
||||
video_blit_memtoscreen(0, dev->firstline - 8, xsize, (dev->lastline - dev->firstline) + 16);
|
||||
else
|
||||
video_blit_memtoscreen(8, dev->firstline, xsize, dev->lastline - dev->firstline);
|
||||
}
|
||||
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
if (enable_overscan)
|
||||
xsize -= 16;
|
||||
video_res_y = ysize;
|
||||
if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= dev->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(dev->cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= dev->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(dev->cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
|
||||
dev->firstline = 1000;
|
||||
dev->lastline = 0;
|
||||
dev->cgablink++;
|
||||
dev->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
}
|
||||
|
||||
if (dev->cgadispon)
|
||||
dev->cgastat &= ~1;
|
||||
|
||||
if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->cursorvisible = 1;
|
||||
|
||||
if (dev->cgadispon && (dev->cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
for (x = 0; x < (dev->crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
dev->charbuffer[x] = dev->vram[((dev->memaddr << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_cga_init(const device_t *info)
|
||||
{
|
||||
int display_type;
|
||||
cga_t *dev = calloc(1, sizeof(cga_t));
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
dev->composite = (display_type != CGA_RGB);
|
||||
dev->revision = device_get_config_int("composite_type");
|
||||
dev->snow_enabled = device_get_config_int("snow_enabled");
|
||||
|
||||
dev->vram = malloc(0x4000);
|
||||
|
||||
cga_comp_init(dev->revision);
|
||||
timer_add(&dev->timer, compaq_cga_poll, dev, 1);
|
||||
mem_mapping_add(&dev->mapping, 0xb8000, 0x08000,
|
||||
cga_read, NULL, NULL,
|
||||
cga_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
io_sethandler(0x03d0, 0x0010,
|
||||
cga_in, NULL, NULL,
|
||||
cga_out, NULL, NULL,
|
||||
dev);
|
||||
|
||||
if (info->local) {
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
vflags = info->local;
|
||||
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
dev->rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (dev->rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
|
||||
dev->crtc[9] = 13;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_cga_close(void *priv)
|
||||
{
|
||||
cga_t *dev = (cga_t *) priv;
|
||||
|
||||
free(dev->vram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_cga_speed_changed(void *priv)
|
||||
{
|
||||
cga_t *dev = (cga_t *) priv;
|
||||
|
||||
if (dev->crtc[9] == 13) /* Character height */
|
||||
compaq_cga_recalctimings(dev);
|
||||
else
|
||||
cga_recalctimings(dev);
|
||||
}
|
||||
|
||||
extern const device_config_t cga_config[];
|
||||
|
||||
const device_t compaq_cga_device = {
|
||||
.name = "Compaq CGA",
|
||||
.internal_name = "compaq_cga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
const device_t compaq_cga_2_device = {
|
||||
.name = "Compaq CGA 2",
|
||||
.internal_name = "compaq_cga_2",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
843
src/video/vid_cga_compaq_plasma.c
Normal file
843
src/video/vid_cga_compaq_plasma.c
Normal file
@@ -0,0 +1,843 @@
|
||||
/*
|
||||
* 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 plasma displays on early Compaq Portables and laptops.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
/*Very rough estimate*/
|
||||
#define VID_CLOCK (double) (651 * 416 * 60)
|
||||
|
||||
/* Mapping of attributes to colours */
|
||||
static uint32_t amber;
|
||||
static uint32_t black;
|
||||
static uint32_t blinkcols[256][2];
|
||||
static uint32_t normcols[256][2];
|
||||
|
||||
/* Video options set by the motherboard; they will be picked up by the card
|
||||
* on the next poll.
|
||||
*
|
||||
* Bit 3: Disable built-in video (for add-on card)
|
||||
* Bit 2: Thin font
|
||||
* Bits 0,1: Font set (not currently implemented)
|
||||
*/
|
||||
static int8_t cpq_st_display_internal = -1;
|
||||
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
static void
|
||||
compaq_plasma_display_set(uint8_t internal)
|
||||
{
|
||||
cpq_st_display_internal = internal;
|
||||
}
|
||||
|
||||
typedef struct compaq_plasma_t {
|
||||
cga_t cga;
|
||||
mem_mapping_t font_ram_mapping;
|
||||
uint8_t *font_ram;
|
||||
uint8_t port_13c6;
|
||||
uint8_t port_23c6;
|
||||
uint8_t port_27c6;
|
||||
uint8_t internal_monitor;
|
||||
} compaq_plasma_t;
|
||||
|
||||
|
||||
static void compaq_plasma_recalcattrs(compaq_plasma_t *self);
|
||||
|
||||
static void
|
||||
compaq_plasma_recalctimings(compaq_plasma_t *self)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
cga_recalctimings(&self->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_waitstates(UNUSED(void *priv))
|
||||
{
|
||||
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
self->font_ram[addr & 0x1fff] = val;
|
||||
else
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
}
|
||||
static uint8_t
|
||||
compaq_plasma_read(uint32_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
ret = (self->font_ram[addr & 0x1fff]);
|
||||
else
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
/* Emulated CRTC, register select */
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
/* Emulated CRTC, value */
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
cga_out(addr, val, &self->cga);
|
||||
compaq_plasma_recalctimings(self);
|
||||
break;
|
||||
case 0x3d8:
|
||||
case 0x3d9:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
self->port_13c6 = val;
|
||||
compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0);
|
||||
/*
|
||||
For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA;
|
||||
Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA;
|
||||
This leads me to believe bit 2 is not relevant to the mode.
|
||||
*/
|
||||
if ((val & 0x07) == 0x03)
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000);
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
self->port_23c6 = val;
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
self->port_27c6 = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_in(uint16_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d4:
|
||||
case 0x3da:
|
||||
case 0x3db:
|
||||
case 0x3dc:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d8:
|
||||
ret = self->cga.cgamode;
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
ret = self->port_13c6;
|
||||
break;
|
||||
|
||||
case 0x17c6:
|
||||
ret = 0xe6;
|
||||
break;
|
||||
|
||||
case 0x1bc6:
|
||||
ret = 0x40;
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
ret = self->port_23c6;
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
ret = self->port_27c6 & 0x3f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_poll(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (self->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (self->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
uint16_t cursoraddr = (self->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (self->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
uint16_t addr;
|
||||
int drawcursor;
|
||||
int cursorline;
|
||||
int blink = 0;
|
||||
int underline = 0;
|
||||
int cursorvisible = 0;
|
||||
int cursorinvisible = 0;
|
||||
int c;
|
||||
int x;
|
||||
uint32_t ink = 0;
|
||||
uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black;
|
||||
uint32_t bg = black;
|
||||
uint32_t black_half = black;
|
||||
uint32_t amber_half = amber;
|
||||
uint32_t cols[2];
|
||||
uint8_t dat;
|
||||
uint8_t pattern;
|
||||
uint32_t ink0 = 0;
|
||||
uint32_t ink1 = 0;
|
||||
|
||||
/* Switch between internal plasma and external CRT display. */
|
||||
if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) {
|
||||
self->internal_monitor = cpq_st_display_internal;
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
/* graphic mode and not mode 40h */
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
} else {
|
||||
/* mode 40h or text mode */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine == 0)
|
||||
video_wait_for_buffer();
|
||||
|
||||
/* 80-col */
|
||||
if (self->cga.cgamode & 0x01) {
|
||||
scanline = self->cga.displine & 0x0f;
|
||||
addr = ((memaddr & ~1) + (self->cga.displine >> 4) * 80) << 1;
|
||||
memaddr += (self->cga.displine >> 4) * 80;
|
||||
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else {
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) > 0x07)
|
||||
cursorvisible = (self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) + 1;
|
||||
else
|
||||
cursorvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) << 1);
|
||||
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) > 0x07)
|
||||
cursorinvisible = (self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) + 2;
|
||||
else
|
||||
cursorinvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) << 1);
|
||||
|
||||
cursorline = (cursorvisible <= scanline) && (cursorinvisible >= scanline);
|
||||
}
|
||||
|
||||
/* for each text column */
|
||||
for (x = 0; x < 80; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 1) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + scanline) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 4) {
|
||||
uint8_t b = (cols[1] & 0xff) >> 1;
|
||||
uint8_t g = ((cols[1] >> 8) & 0xff) >> 1;
|
||||
uint8_t r = ((cols[1] >> 16) & 0xff) >> 1;
|
||||
cols[1] = b | (g << 8) | (r << 16);
|
||||
b = (cols[0] & 0xff) >> 1;
|
||||
g = ((cols[0] >> 8) & 0xff) >> 1;
|
||||
r = ((cols[0] >> 16) & 0xff) >> 1;
|
||||
cols[0] = b | (g << 8) | (r << 16);
|
||||
if (drawcursor) {
|
||||
black_half = black;
|
||||
amber_half = amber;
|
||||
uint8_t bB = (black & 0xff) >> 1;
|
||||
uint8_t gB = ((black >> 8) & 0xff) >> 1;
|
||||
uint8_t rB = ((black >> 16) & 0xff) >> 1;
|
||||
black_half = bB | (gB << 8) | (rB << 16);
|
||||
uint8_t bA = (amber & 0xff) >> 1;
|
||||
uint8_t gA = ((amber >> 8) & 0xff) >> 1;
|
||||
uint8_t rA = ((amber >> 16) & 0xff) >> 1;
|
||||
amber_half = bA | (gA << 8) | (rA << 16);
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber_half ^ black_half);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
} else if ((self->port_23c6 >> 5) == 2) {
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
memaddr++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(self->cga.cgamode & 0x02)) {
|
||||
scanline = self->cga.displine & 0x0f;
|
||||
addr = ((memaddr & ~1) + (self->cga.displine >> 4) * 40) << 1;
|
||||
memaddr += (self->cga.displine >> 4) * 40;
|
||||
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else {
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) > 0x07)
|
||||
cursorvisible = (self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) + 1;
|
||||
else
|
||||
cursorvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) << 1);
|
||||
|
||||
if ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) > 0x07)
|
||||
cursorinvisible = (self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) + 2;
|
||||
else
|
||||
cursorinvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) << 1);
|
||||
|
||||
cursorline = (cursorvisible <= scanline) && (cursorinvisible >= scanline);
|
||||
}
|
||||
|
||||
for (x = 0; x < 40; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 1) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + scanline) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (scanline == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 4) {
|
||||
uint8_t b = (cols[1] & 0xff) >> 1;
|
||||
uint8_t g = ((cols[1] >> 8) & 0xff) >> 1;
|
||||
uint8_t r = ((cols[1] >> 16) & 0xff) >> 1;
|
||||
cols[1] = b | (g << 8) | (r << 16);
|
||||
b = (cols[0] & 0xff) >> 1;
|
||||
g = ((cols[0] >> 8) & 0xff) >> 1;
|
||||
r = ((cols[0] >> 16) & 0xff) >> 1;
|
||||
cols[0] = b | (g << 8) | (r << 16);
|
||||
if (drawcursor) {
|
||||
black_half = black;
|
||||
amber_half = amber;
|
||||
uint8_t bB = (black & 0xff) >> 1;
|
||||
uint8_t gB = ((black >> 8) & 0xff) >> 1;
|
||||
uint8_t rB = ((black >> 16) & 0xff) >> 1;
|
||||
black_half = bB | (gB << 8) | (rB << 16);
|
||||
uint8_t bA = (amber & 0xff) >> 1;
|
||||
uint8_t gA = ((amber >> 8) & 0xff) >> 1;
|
||||
uint8_t rA = ((amber >> 16) & 0xff) >> 1;
|
||||
amber_half = bA | (gA << 8) | (rA << 16);
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber_half ^ black_half);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
} else if ((self->port_23c6 >> 5) == 2) {
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
memaddr++;
|
||||
}
|
||||
} else {
|
||||
if (self->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) {
|
||||
/* 640x400 mode */
|
||||
if (self->port_23c6 & 0x01) /* 640*400 */ {
|
||||
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
ink = black;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = ink;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
case 0:
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = amber;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ink0 = ink1 = amber;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1)] = ink0;
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1) + 1] = ink1;
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self->cga.displine++;
|
||||
/* Hardcode a fixed refresh rate and VSYNC timing */
|
||||
if (self->cga.displine == 400) { /* Start of VSYNC */
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.cgadispon = 0;
|
||||
}
|
||||
if (self->cga.displine == 416) { /* End of VSYNC */
|
||||
self->cga.displine = 0;
|
||||
self->cga.cgastat &= ~8;
|
||||
self->cga.cgadispon = 1;
|
||||
}
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
self->cga.linepos = 0;
|
||||
|
||||
if (self->cga.displine == 400) {
|
||||
xsize = 640;
|
||||
ysize = 400;
|
||||
|
||||
if ((self->cga.cgamode & 0x08) || video_force_resize_get()) {
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
/* Plasma specific */
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* Fixed 640x400 resolution */
|
||||
video_res_x = 640;
|
||||
video_res_y = 400;
|
||||
|
||||
if (self->cga.cgamode & 0x02) {
|
||||
if (self->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 0;
|
||||
|
||||
self->cga.cgablink++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_mdaattr_rebuild(void)
|
||||
{
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* val behaves as follows:
|
||||
* Bit 0: Attributes 01-06, 08-0E are inverse video
|
||||
* Bit 1: Attributes 01-06, 08-0E are bold
|
||||
* Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are inverse video
|
||||
* Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are bold */
|
||||
|
||||
/* Set up colours */
|
||||
amber = makecol(0xff, 0x7d, 0x00);
|
||||
black = makecol(0x64, 0x19, 0x00);
|
||||
|
||||
/* Initialize the attribute mapping. Start by defaulting everything
|
||||
* to black on amber, and with bold set by bit 3 */
|
||||
for (n = 0; n < 256; n++) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
}
|
||||
|
||||
/* Colours 0x11-0xFF are controlled by bits 2 and 3 of the
|
||||
* passed value. Exclude x0 and x8, which are always black on
|
||||
* amber. */
|
||||
for (n = 0x11; n <= 0xFF; n++) {
|
||||
if ((n & 7) == 0)
|
||||
continue;
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
}
|
||||
/* Set up the 01-0E range, controlled by bits 0 and 1 of the
|
||||
* passed value. When blinking is enabled this also affects 81-8E. */
|
||||
for (n = 0x01; n <= 0x0E; n++) {
|
||||
if (n == 7)
|
||||
continue;
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
/* Colours 07 and 0F are always amber on black. If blinking is
|
||||
* enabled so are 87 and 8F. */
|
||||
for (n = 0x07; n <= 0x0F; n += 8) {
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
/* When not blinking, colours 81-8F are always amber on black. */
|
||||
for (n = 0x81; n <= 0x8F; n++) {
|
||||
normcols[n][0] = black;
|
||||
normcols[n][1] = amber;
|
||||
}
|
||||
|
||||
/* Finally do the ones which are solid black. These differ between
|
||||
* the normal and blinking mappings */
|
||||
for (n = 0; n <= 0xFF; n += 0x11)
|
||||
normcols[n][0] = normcols[n][1] = black;
|
||||
|
||||
/* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */
|
||||
for (n = 0; n <= 0x77; n += 0x11) {
|
||||
blinkcols[n][0] = blinkcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = blinkcols[n + 128][1] = black;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_plasma_init(UNUSED(const device_t *info))
|
||||
{
|
||||
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
|
||||
|
||||
cga_init(&self->cga);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
|
||||
|
||||
self->cga.composite = 0;
|
||||
self->cga.revision = 0;
|
||||
|
||||
self->cga.vram = malloc(0x8000);
|
||||
self->internal_monitor = 1;
|
||||
self->font_ram = malloc(0x2000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_set_callback(&self->cga.timer, compaq_plasma_poll);
|
||||
timer_set_p(&self->cga.timer, self);
|
||||
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000,
|
||||
compaq_plasma_read, NULL, NULL,
|
||||
compaq_plasma_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
}
|
||||
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
|
||||
overscan_x = overscan_y = 16;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
compaq_plasma_mdaattr_rebuild();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_close(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self->font_ram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_speed_changed(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
const device_config_t compaq_plasma_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "RGB type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Color", .value = 0 },
|
||||
{ .description = "Green Monochrome", .value = 1 },
|
||||
{ .description = "Amber Monochrome", .value = 2 },
|
||||
{ .description = "Gray Monochrome", .value = 3 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t compaq_plasma_device = {
|
||||
.name = "Compaq Plasma",
|
||||
.internal_name = "compaq_plasma",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_plasma_init,
|
||||
.close = compaq_plasma_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_plasma_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = compaq_plasma_config
|
||||
};
|
||||
@@ -56,12 +56,12 @@ nga_recalctimings(nga_t *nga)
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (nga->cga.cgamode & 1) {
|
||||
disptime = nga->cga.crtc[0] + 1;
|
||||
_dispontime = nga->cga.crtc[1];
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
disptime = nga->cga.crtc[CGA_CRTC_HTOTAL] + 1;
|
||||
_dispontime = nga->cga.crtc[CGA_CRTC_HDISP];
|
||||
} else {
|
||||
disptime = (nga->cga.crtc[0] + 1) << 1;
|
||||
_dispontime = nga->cga.crtc[1] << 1;
|
||||
disptime = (nga->cga.crtc[CGA_CRTC_HTOTAL] + 1) << 1;
|
||||
_dispontime = nga->cga.crtc[CGA_CRTC_HDISP] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
@@ -148,7 +148,7 @@ nga_poll(void *priv)
|
||||
{
|
||||
nga_t *nga = (nga_t *) priv;
|
||||
/* set cursor position in memory */
|
||||
uint16_t ca = (nga->cga.crtc[15] | (nga->cga.crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (nga->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
@@ -161,10 +161,10 @@ nga_poll(void *priv)
|
||||
uint16_t dat2;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
|
||||
/* graphic mode and not high-res modes */
|
||||
if ((nga->cga.cgamode & 2) && !(nga->cga.cgamode & 0x40)) {
|
||||
if ((nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) && !(nga->cga.cgamode & 0x40)) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&nga->cga);
|
||||
return;
|
||||
@@ -174,10 +174,10 @@ nga_poll(void *priv)
|
||||
timer_advance_u64(&nga->cga.timer, nga->cga.dispofftime);
|
||||
nga->cga.cgastat |= 1;
|
||||
nga->cga.linepos = 1;
|
||||
oldsc = nga->cga.sc;
|
||||
scanline_old = nga->cga.scanline;
|
||||
/* if interlaced */
|
||||
if ((nga->cga.crtc[8] & 3) == 3)
|
||||
nga->cga.sc = ((nga->cga.sc << 1) + nga->cga.oddeven) & 7;
|
||||
if ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
nga->cga.scanline = ((nga->cga.scanline << 1) + nga->cga.oddeven) & 7;
|
||||
if (nga->cga.cgadispon) {
|
||||
if (nga->cga.displine < nga->cga.firstline) {
|
||||
nga->cga.firstline = nga->cga.displine;
|
||||
@@ -185,11 +185,11 @@ nga_poll(void *priv)
|
||||
}
|
||||
nga->cga.lastline = nga->cga.displine;
|
||||
/* 80-col */
|
||||
if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 2)) {
|
||||
if ((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && !(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
/* for each text column */
|
||||
for (x = 0; x < nga->cga.crtc[1]; x++) {
|
||||
for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
/* video output enabled */
|
||||
if (nga->cga.cgamode & 8) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
/* character */
|
||||
chr = nga->cga.charbuffer[x << 1];
|
||||
/* text attributes */
|
||||
@@ -197,11 +197,11 @@ nga_poll(void *priv)
|
||||
} else
|
||||
chr = attr = 0;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron);
|
||||
drawcursor = ((nga->cga.memaddr == cursoraddr) && nga->cga.cursorvisible && nga->cga.cursoron);
|
||||
/* set foreground */
|
||||
cols[1] = (attr & 15) + 16;
|
||||
/* blink active */
|
||||
if (nga->cga.cgamode & 0x20) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) {
|
||||
@@ -214,30 +214,30 @@ nga_poll(void *priv)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
nga->cga.ma++;
|
||||
nga->cga.memaddr++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(nga->cga.cgamode & 2)) {
|
||||
else if (!(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
/* for each text column */
|
||||
for (x = 0; x < nga->cga.crtc[1]; x++) {
|
||||
if (nga->cga.cgamode & 8) {
|
||||
chr = nga->cga.vram[((nga->cga.ma << 1) & 0x3fff) + nga->base];
|
||||
attr = nga->cga.vram[(((nga->cga.ma << 1) + 1) & 0x3fff) + nga->base];
|
||||
for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
chr = nga->cga.vram[((nga->cga.memaddr << 1) & 0x3fff) + nga->base];
|
||||
attr = nga->cga.vram[(((nga->cga.memaddr << 1) + 1) & 0x3fff) + nga->base];
|
||||
} else {
|
||||
chr = attr = 0;
|
||||
}
|
||||
drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron);
|
||||
drawcursor = ((nga->cga.memaddr == cursoraddr) && nga->cga.cursorvisible && nga->cga.cursoron);
|
||||
/* set foreground */
|
||||
cols[1] = (attr & 15) + 16;
|
||||
/* blink active */
|
||||
if (nga->cga.cgamode & 0x20) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) {
|
||||
/* set blinking */
|
||||
@@ -250,19 +250,19 @@ nga_poll(void *priv)
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
nga->cga.ma++;
|
||||
nga->cga.memaddr++;
|
||||
}
|
||||
} else {
|
||||
/* high res modes */
|
||||
if (nga->cga.cgamode & 0x40) {
|
||||
/* 640x400x2 mode */
|
||||
if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) {
|
||||
if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) {
|
||||
/*
|
||||
* Scanlines are read in the following order:
|
||||
* 0b8000-0b9f3f even scans (0,4,...)
|
||||
@@ -270,14 +270,14 @@ nga_poll(void *priv)
|
||||
* 0bc000-0bdf3f even scans (1,5,...)
|
||||
* 0be000-0bff3f odd scans (3,7,...)
|
||||
*/
|
||||
dat2 = ((nga->cga.sc & 1) * 0x2000) | (nga->lineff * 0x4000);
|
||||
dat2 = ((nga->cga.scanline & 1) * 0x2000) | (nga->lineff * 0x4000);
|
||||
cols[0] = 0;
|
||||
cols[1] = 15 + 16;
|
||||
/* 640x400x4 mode */
|
||||
} else {
|
||||
cols[0] = (nga->cga.cgacol & 15) | 16;
|
||||
col = (nga->cga.cgacol & 16) ? 24 : 16;
|
||||
if (nga->cga.cgamode & 4) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_BW) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 7; /* White */
|
||||
@@ -297,22 +297,22 @@ nga_poll(void *priv)
|
||||
* 0a8000-0abf3f even scans (2,6,...)
|
||||
* 0ac000-0aff3f odd scans (3,7,...)
|
||||
*/
|
||||
dat2 = (nga->cga.sc & 1) * 0x4000;
|
||||
dat2 = (nga->cga.scanline & 1) * 0x4000;
|
||||
}
|
||||
} else {
|
||||
dat2 = (nga->cga.sc & 1) * 0x2000;
|
||||
dat2 = (nga->cga.scanline & 1) * 0x2000;
|
||||
cols[0] = 0;
|
||||
cols[1] = (nga->cga.cgacol & 15) + 16;
|
||||
}
|
||||
|
||||
/* for each text column */
|
||||
for (x = 0; x < nga->cga.crtc[1]; x++) {
|
||||
for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
/* video out */
|
||||
if (nga->cga.cgamode & 8) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
/* 640x400x2 */
|
||||
if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) {
|
||||
if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) {
|
||||
/* read two bytes at a time */
|
||||
dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2 + 1];
|
||||
dat = (nga->cga.vram[((nga->cga.memaddr << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.memaddr << 1) & 0x1fff) + dat2 + 1];
|
||||
/* each pixel is represented by one bit, so draw 16 pixels at a time */
|
||||
/* crtc[1] is 40 column, so 40x16=640 pixels */
|
||||
for (c = 0; c < 16; c++) {
|
||||
@@ -322,13 +322,13 @@ nga_poll(void *priv)
|
||||
/* 640x400x4 */
|
||||
} else {
|
||||
/* lines 2,3,6,7,etc. */
|
||||
if (nga->cga.sc & 2)
|
||||
if (nga->cga.scanline & 2)
|
||||
/* read two bytes at a time */
|
||||
dat = (nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1];
|
||||
dat = (nga->vram_64k[((nga->cga.memaddr << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.memaddr << 1) & 0x7fff) + dat2 + 1];
|
||||
/* lines 0,1,4,5,etc. */
|
||||
else
|
||||
/* read two bytes at a time */
|
||||
dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1];
|
||||
dat = (nga->cga.vram[((nga->cga.memaddr << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.memaddr << 1) & 0x7fff) + dat2 + 1];
|
||||
/* each pixel is represented by two bits, so draw 8 pixels at a time */
|
||||
/* crtc[1] is 80 column, so 80x8=640 pixels */
|
||||
for (c = 0; c < 8; c++) {
|
||||
@@ -339,7 +339,7 @@ nga_poll(void *priv)
|
||||
} else {
|
||||
dat = 0;
|
||||
}
|
||||
nga->cga.ma++;
|
||||
nga->cga.memaddr++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -347,26 +347,26 @@ nga_poll(void *priv)
|
||||
/* nga specific */
|
||||
cols[0] = ((nga->cga.cgamode & 0x12) == 0x12) ? 0 : (nga->cga.cgacol & 15) + 16;
|
||||
/* 80-col */
|
||||
if (nga->cga.cgamode & 1) {
|
||||
hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (nga->cga.cgamode & 1)
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
/* set screen width */
|
||||
x = (nga->cga.crtc[1] << 3) + 16;
|
||||
x = (nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (nga->cga.crtc[1] << 4) + 16;
|
||||
x = (nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
video_process_8(x, nga->cga.displine);
|
||||
|
||||
nga->cga.sc = oldsc;
|
||||
nga->cga.scanline = scanline_old;
|
||||
/* vertical sync */
|
||||
if (nga->cga.vc == nga->cga.crtc[7] && !nga->cga.sc)
|
||||
if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VSYNC] && !nga->cga.scanline)
|
||||
nga->cga.cgastat |= 8;
|
||||
nga->cga.displine++;
|
||||
if (nga->cga.displine >= 720)
|
||||
@@ -380,8 +380,8 @@ nga_poll(void *priv)
|
||||
nga->lineff ^= 1;
|
||||
|
||||
/* text mode or 640x400x2 */
|
||||
if (nga->lineff && !((nga->cga.cgamode & 1) && (nga->cga.cgamode & 0x40))) {
|
||||
nga->cga.ma = nga->cga.maback;
|
||||
if (nga->lineff && !((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && (nga->cga.cgamode & 0x40))) {
|
||||
nga->cga.memaddr = nga->cga.memaddr_backup;
|
||||
/* 640x400x4 */
|
||||
} else {
|
||||
if (nga->cga.vsynctime) {
|
||||
@@ -390,50 +390,49 @@ nga_poll(void *priv)
|
||||
nga->cga.cgastat &= ~8;
|
||||
}
|
||||
/* cursor stop scanline */
|
||||
if (nga->cga.sc == (nga->cga.crtc[11] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[11] & 31) >> 1))) {
|
||||
nga->cga.con = 0;
|
||||
nga->cga.coff = 1;
|
||||
if (nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_CURSOR_END] & 31) || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == ((nga->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
nga->cga.cursorvisible = 0;
|
||||
}
|
||||
/* interlaced and max scanline per char reached */
|
||||
if ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))
|
||||
nga->cga.maback = nga->cga.ma;
|
||||
if ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
nga->cga.memaddr_backup = nga->cga.memaddr;
|
||||
|
||||
if (nga->cga.vadj) {
|
||||
nga->cga.sc++;
|
||||
nga->cga.sc &= 31;
|
||||
nga->cga.ma = nga->cga.maback;
|
||||
nga->cga.scanline++;
|
||||
nga->cga.scanline &= 31;
|
||||
nga->cga.memaddr = nga->cga.memaddr_backup;
|
||||
nga->cga.vadj--;
|
||||
if (!nga->cga.vadj) {
|
||||
nga->cga.cgadispon = 1;
|
||||
/* change start of displayed page (crtc 12-13) */
|
||||
nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff;
|
||||
nga->cga.sc = 0;
|
||||
nga->cga.memaddr = nga->cga.memaddr_backup = (nga->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
nga->cga.scanline = 0;
|
||||
}
|
||||
/* nga specific */
|
||||
/* end of character line reached */
|
||||
} else if (nga->cga.sc == nga->cga.crtc[9] || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))) {
|
||||
nga->cga.maback = nga->cga.ma;
|
||||
nga->cga.sc = 0;
|
||||
} else if (nga->cga.scanline == nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))) {
|
||||
nga->cga.memaddr_backup = nga->cga.memaddr;
|
||||
nga->cga.scanline = 0;
|
||||
oldvc = nga->cga.vc;
|
||||
nga->cga.vc++;
|
||||
nga->cga.vc &= 127;
|
||||
|
||||
/* lines of character displayed */
|
||||
if (nga->cga.vc == nga->cga.crtc[6])
|
||||
if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VDISP])
|
||||
nga->cga.cgadispon = 0;
|
||||
|
||||
/* total vertical lines */
|
||||
if (oldvc == nga->cga.crtc[4]) {
|
||||
if (oldvc == nga->cga.crtc[CGA_CRTC_VTOTAL]) {
|
||||
nga->cga.vc = 0;
|
||||
/* adjust vertical lines */
|
||||
nga->cga.vadj = nga->cga.crtc[5];
|
||||
nga->cga.vadj = nga->cga.crtc[CGA_CRTC_VTOTAL_ADJUST];
|
||||
if (!nga->cga.vadj) {
|
||||
nga->cga.cgadispon = 1;
|
||||
/* change start of displayed page (crtc 12-13) */
|
||||
nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff;
|
||||
nga->cga.memaddr = nga->cga.memaddr_backup = (nga->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
}
|
||||
/* cursor start */
|
||||
switch (nga->cga.crtc[10] & 0x60) {
|
||||
switch (nga->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) {
|
||||
case 0x20:
|
||||
nga->cga.cursoron = 0;
|
||||
break;
|
||||
@@ -446,18 +445,18 @@ nga_poll(void *priv)
|
||||
}
|
||||
}
|
||||
/* vertical line position */
|
||||
if (nga->cga.vc == nga->cga.crtc[7]) {
|
||||
if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
nga->cga.cgadispon = 0;
|
||||
nga->cga.displine = 0;
|
||||
/* nga specific */
|
||||
nga->cga.vsynctime = 16;
|
||||
/* vsync pos */
|
||||
if (nga->cga.crtc[7]) {
|
||||
if (nga->cga.cgamode & 1)
|
||||
if (nga->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
/* set screen width */
|
||||
x = (nga->cga.crtc[1] << 3) + 16;
|
||||
x = (nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (nga->cga.crtc[1] << 4) + 16;
|
||||
x = (nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
nga->cga.lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
@@ -472,7 +471,7 @@ nga_poll(void *priv)
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((nga->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
if ((nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
@@ -494,14 +493,14 @@ nga_poll(void *priv)
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
/* 80-col */
|
||||
if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 0x40)) {
|
||||
if ((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && !(nga->cga.cgamode & 0x40)) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= (nga->cga.crtc[9] + 1) * 2;
|
||||
video_res_y /= (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
/* 40-col */
|
||||
} else if (!(nga->cga.cgamode & 2)) {
|
||||
} else if (!(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= (nga->cga.crtc[9] + 1) * 2;
|
||||
video_res_y /= (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
} else if (nga->cga.cgamode & 0x40) {
|
||||
video_res_x /= 8;
|
||||
@@ -515,23 +514,23 @@ nga_poll(void *priv)
|
||||
nga->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
nga->cga.sc++;
|
||||
nga->cga.sc &= 31;
|
||||
nga->cga.ma = nga->cga.maback;
|
||||
nga->cga.scanline++;
|
||||
nga->cga.scanline &= 31;
|
||||
nga->cga.memaddr = nga->cga.memaddr_backup;
|
||||
}
|
||||
|
||||
if (nga->cga.cgadispon)
|
||||
nga->cga.cgastat &= ~1;
|
||||
|
||||
/* enable cursor if its scanline was reached */
|
||||
if (nga->cga.sc == (nga->cga.crtc[10] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[10] & 31) >> 1)))
|
||||
nga->cga.con = 1;
|
||||
if (nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == ((nga->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
nga->cga.cursorvisible = 1;
|
||||
}
|
||||
/* 80-columns */
|
||||
if (nga->cga.cgadispon && (nga->cga.cgamode & 1)) {
|
||||
if (nga->cga.cgadispon && (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
/* for each character per line */
|
||||
for (x = 0; x < (nga->cga.crtc[1] << 1); x++)
|
||||
nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.ma << 1) + x) & 0x3fff) + nga->base];
|
||||
for (x = 0; x < (nga->cga.crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.memaddr << 1) + x) & 0x3fff) + nga->base];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,12 +65,12 @@ ogc_recalctimings(ogc_t *ogc)
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (ogc->cga.cgamode & 1) {
|
||||
disptime = ogc->cga.crtc[0] + 1;
|
||||
_dispontime = ogc->cga.crtc[1];
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
disptime = ogc->cga.crtc[CGA_CRTC_HTOTAL] + 1;
|
||||
_dispontime = ogc->cga.crtc[CGA_CRTC_HDISP];
|
||||
} else {
|
||||
disptime = (ogc->cga.crtc[0] + 1) << 1;
|
||||
_dispontime = ogc->cga.crtc[1] << 1;
|
||||
disptime = (ogc->cga.crtc[CGA_CRTC_HTOTAL] + 1) << 1;
|
||||
_dispontime = ogc->cga.crtc[CGA_CRTC_HDISP] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
@@ -201,7 +201,7 @@ void
|
||||
ogc_poll(void *priv)
|
||||
{
|
||||
ogc_t *ogc = (ogc_t *) priv;
|
||||
uint16_t ca = (ogc->cga.crtc[15] | (ogc->cga.crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (ogc->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
@@ -213,14 +213,14 @@ ogc_poll(void *priv)
|
||||
uint16_t dat;
|
||||
uint16_t dat2;
|
||||
int cols[4];
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int blink = 0;
|
||||
int underline = 0;
|
||||
|
||||
// composito colore appare blu scuro
|
||||
// Composite color appears dark blue
|
||||
|
||||
/* graphic mode and not mode 40h */
|
||||
if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & 2))) {
|
||||
if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS))) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&ogc->cga);
|
||||
return;
|
||||
@@ -230,9 +230,9 @@ ogc_poll(void *priv)
|
||||
timer_advance_u64(&ogc->cga.timer, ogc->cga.dispofftime);
|
||||
ogc->cga.cgastat |= 1;
|
||||
ogc->cga.linepos = 1;
|
||||
oldsc = ogc->cga.sc;
|
||||
if ((ogc->cga.crtc[8] & 3) == 3)
|
||||
ogc->cga.sc = ((ogc->cga.sc << 1) + ogc->cga.oddeven) & 7;
|
||||
scanline_old = ogc->cga.scanline;
|
||||
if ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
ogc->cga.scanline = ((ogc->cga.scanline << 1) + ogc->cga.oddeven) & 7;
|
||||
if (ogc->cga.cgadispon) {
|
||||
if (ogc->cga.displine < ogc->cga.firstline) {
|
||||
ogc->cga.firstline = ogc->cga.displine;
|
||||
@@ -240,11 +240,11 @@ ogc_poll(void *priv)
|
||||
}
|
||||
ogc->cga.lastline = ogc->cga.displine;
|
||||
/* 80-col */
|
||||
if (ogc->cga.cgamode & 1) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
/* for each text column */
|
||||
for (x = 0; x < ogc->cga.crtc[1]; x++) {
|
||||
for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
/* video output enabled */
|
||||
if (ogc->cga.cgamode & 8) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
/* character */
|
||||
chr = ogc->cga.charbuffer[x << 1];
|
||||
/* text attributes */
|
||||
@@ -252,7 +252,7 @@ ogc_poll(void *priv)
|
||||
} else
|
||||
chr = attr = 0;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron);
|
||||
drawcursor = ((ogc->cga.memaddr == cursoraddr) && ogc->cga.cursorvisible && ogc->cga.cursoron);
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6));
|
||||
if (underline) {
|
||||
@@ -263,7 +263,7 @@ ogc_poll(void *priv)
|
||||
/* set foreground */
|
||||
cols[1] = (attr & 15) + 16;
|
||||
/* blink active */
|
||||
if (ogc->cga.cgamode & 0x20) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) {
|
||||
@@ -277,31 +277,31 @@ ogc_poll(void *priv)
|
||||
blink = (attr & 0x80) * 8 + 7 + 16;
|
||||
}
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (ogc->cga.sc == 7)) {
|
||||
if (underline && (ogc->cga.scanline == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
ogc->cga.ma++;
|
||||
ogc->cga.memaddr++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(ogc->cga.cgamode & 2)) {
|
||||
for (x = 0; x < ogc->cga.crtc[1]; x++) {
|
||||
if (ogc->cga.cgamode & 8) {
|
||||
chr = ogc->cga.vram[((ogc->cga.ma << 1) & 0x3fff) + ogc->base];
|
||||
attr = ogc->cga.vram[(((ogc->cga.ma << 1) + 1) & 0x3fff) + ogc->base];
|
||||
else if (!(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
chr = ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x3fff) + ogc->base];
|
||||
attr = ogc->cga.vram[(((ogc->cga.memaddr << 1) + 1) & 0x3fff) + ogc->base];
|
||||
} else {
|
||||
chr = attr = 0;
|
||||
}
|
||||
drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron);
|
||||
drawcursor = ((ogc->cga.memaddr == cursoraddr) && ogc->cga.cursorvisible && ogc->cga.cursoron);
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6));
|
||||
if (underline) {
|
||||
@@ -312,7 +312,7 @@ ogc_poll(void *priv)
|
||||
/* set foreground */
|
||||
cols[1] = (attr & 15) + 16;
|
||||
/* blink active */
|
||||
if (ogc->cga.cgamode & 0x20) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) {
|
||||
/* set blinking */
|
||||
@@ -326,40 +326,40 @@ ogc_poll(void *priv)
|
||||
}
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (ogc->cga.sc == 7)) {
|
||||
if (underline && (ogc->cga.scanline == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
ogc->cga.ma++;
|
||||
ogc->cga.memaddr++;
|
||||
}
|
||||
} else {
|
||||
/* 640x400 mode */
|
||||
if (ogc->ctrl_3de & 1) {
|
||||
dat2 = ((ogc->cga.sc & 1) * 0x4000) | (ogc->lineff * 0x2000);
|
||||
dat2 = ((ogc->cga.scanline & 1) * 0x4000) | (ogc->lineff * 0x2000);
|
||||
cols[0] = 0;
|
||||
cols[1] = 15 + 16;
|
||||
} else {
|
||||
dat2 = (ogc->cga.sc & 1) * 0x2000;
|
||||
dat2 = (ogc->cga.scanline & 1) * 0x2000;
|
||||
cols[0] = 0;
|
||||
cols[1] = (ogc->cga.cgacol & 15) + 16;
|
||||
}
|
||||
|
||||
for (x = 0; x < ogc->cga.crtc[1]; x++) {
|
||||
for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) {
|
||||
/* video out */
|
||||
if (ogc->cga.cgamode & 8) {
|
||||
dat = (ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2 + 1];
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
|
||||
dat = (ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x1fff) + dat2 + 1];
|
||||
} else {
|
||||
dat = 0;
|
||||
}
|
||||
ogc->cga.ma++;
|
||||
ogc->cga.memaddr++;
|
||||
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[ogc->cga.displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
@@ -370,22 +370,22 @@ ogc_poll(void *priv)
|
||||
} else {
|
||||
/* ogc specific */
|
||||
cols[0] = ((ogc->cga.cgamode & 0x12) == 0x12) ? 0 : (ogc->cga.cgacol & 15) + 16;
|
||||
if (ogc->cga.cgamode & 1)
|
||||
hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]);
|
||||
else
|
||||
hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]);
|
||||
}
|
||||
|
||||
/* 80 columns */
|
||||
if (ogc->cga.cgamode & 1)
|
||||
x = (ogc->cga.crtc[1] << 3) + 16;
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (ogc->cga.crtc[1] << 4) + 16;
|
||||
x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
|
||||
video_process_8(x, ogc->cga.displine);
|
||||
|
||||
ogc->cga.sc = oldsc;
|
||||
if (ogc->cga.vc == ogc->cga.crtc[7] && !ogc->cga.sc)
|
||||
ogc->cga.scanline = scanline_old;
|
||||
if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VSYNC] && !ogc->cga.scanline)
|
||||
ogc->cga.cgastat |= 8;
|
||||
ogc->cga.displine++;
|
||||
if (ogc->cga.displine >= 720)
|
||||
@@ -398,48 +398,47 @@ ogc_poll(void *priv)
|
||||
/* ogc specific */
|
||||
ogc->lineff ^= 1;
|
||||
if (ogc->lineff) {
|
||||
ogc->cga.ma = ogc->cga.maback;
|
||||
ogc->cga.memaddr = ogc->cga.memaddr_backup;
|
||||
} else {
|
||||
if (ogc->cga.vsynctime) {
|
||||
ogc->cga.vsynctime--;
|
||||
if (!ogc->cga.vsynctime)
|
||||
ogc->cga.cgastat &= ~8;
|
||||
}
|
||||
if (ogc->cga.sc == (ogc->cga.crtc[11] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[11] & 31) >> 1))) {
|
||||
ogc->cga.con = 0;
|
||||
ogc->cga.coff = 1;
|
||||
if (ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_CURSOR_END] & 31) || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == ((ogc->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
ogc->cga.cursorvisible = 0;
|
||||
}
|
||||
if ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))
|
||||
ogc->cga.maback = ogc->cga.ma;
|
||||
if ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
ogc->cga.memaddr_backup = ogc->cga.memaddr;
|
||||
if (ogc->cga.vadj) {
|
||||
ogc->cga.sc++;
|
||||
ogc->cga.sc &= 31;
|
||||
ogc->cga.ma = ogc->cga.maback;
|
||||
ogc->cga.scanline++;
|
||||
ogc->cga.scanline &= 31;
|
||||
ogc->cga.memaddr = ogc->cga.memaddr_backup;
|
||||
ogc->cga.vadj--;
|
||||
if (!ogc->cga.vadj) {
|
||||
ogc->cga.cgadispon = 1;
|
||||
ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff;
|
||||
ogc->cga.sc = 0;
|
||||
ogc->cga.memaddr = ogc->cga.memaddr_backup = (ogc->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
ogc->cga.scanline = 0;
|
||||
}
|
||||
// potrebbe dare problemi con composito
|
||||
} else if (ogc->cga.sc == ogc->cga.crtc[9] || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))) {
|
||||
ogc->cga.maback = ogc->cga.ma;
|
||||
ogc->cga.sc = 0;
|
||||
// may cause problems with composite
|
||||
} else if (ogc->cga.scanline == ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))) {
|
||||
ogc->cga.memaddr_backup = ogc->cga.memaddr;
|
||||
ogc->cga.scanline = 0;
|
||||
oldvc = ogc->cga.vc;
|
||||
ogc->cga.vc++;
|
||||
ogc->cga.vc &= 127;
|
||||
|
||||
if (ogc->cga.vc == ogc->cga.crtc[6])
|
||||
if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VDISP])
|
||||
ogc->cga.cgadispon = 0;
|
||||
|
||||
if (oldvc == ogc->cga.crtc[4]) {
|
||||
if (oldvc == ogc->cga.crtc[CGA_CRTC_VTOTAL]) {
|
||||
ogc->cga.vc = 0;
|
||||
ogc->cga.vadj = ogc->cga.crtc[5];
|
||||
ogc->cga.vadj = ogc->cga.crtc[CGA_CRTC_VTOTAL_ADJUST];
|
||||
if (!ogc->cga.vadj) {
|
||||
ogc->cga.cgadispon = 1;
|
||||
ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff;
|
||||
ogc->cga.memaddr = ogc->cga.memaddr_backup = (ogc->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (ogc->cga.crtc[10] & 0x60) {
|
||||
switch (ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) {
|
||||
case 0x20:
|
||||
ogc->cga.cursoron = 0;
|
||||
break;
|
||||
@@ -451,16 +450,16 @@ ogc_poll(void *priv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ogc->cga.vc == ogc->cga.crtc[7]) {
|
||||
if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
ogc->cga.cgadispon = 0;
|
||||
ogc->cga.displine = 0;
|
||||
/* ogc specific */
|
||||
ogc->cga.vsynctime = (ogc->cga.crtc[3] >> 4) + 1;
|
||||
if (ogc->cga.crtc[7]) {
|
||||
if (ogc->cga.cgamode & 1)
|
||||
x = (ogc->cga.crtc[1] << 3) + 16;
|
||||
ogc->cga.vsynctime = (ogc->cga.crtc[CGA_CRTC_HSYNC_WIDTH] >> 4) + 1;
|
||||
if (ogc->cga.crtc[CGA_CRTC_VSYNC]) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16;
|
||||
else
|
||||
x = (ogc->cga.crtc[1] << 4) + 16;
|
||||
x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16;
|
||||
ogc->cga.lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
@@ -475,7 +474,7 @@ ogc_poll(void *priv)
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((ogc->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
if ((ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
@@ -497,14 +496,14 @@ ogc_poll(void *priv)
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
/* 80-col */
|
||||
if (ogc->cga.cgamode & 1) {
|
||||
if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= (ogc->cga.crtc[9] + 1) * 2;
|
||||
video_res_y /= (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
/* 40-col */
|
||||
} else if (!(ogc->cga.cgamode & 2)) {
|
||||
} else if (!(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= (ogc->cga.crtc[9] + 1) * 2;
|
||||
video_res_y /= (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
} else if (!(ogc->ctrl_3de & 1)) {
|
||||
video_res_y /= 2;
|
||||
@@ -517,21 +516,21 @@ ogc_poll(void *priv)
|
||||
ogc->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
ogc->cga.sc++;
|
||||
ogc->cga.sc &= 31;
|
||||
ogc->cga.ma = ogc->cga.maback;
|
||||
ogc->cga.scanline++;
|
||||
ogc->cga.scanline &= 31;
|
||||
ogc->cga.memaddr = ogc->cga.memaddr_backup;
|
||||
}
|
||||
|
||||
if (ogc->cga.cgadispon)
|
||||
ogc->cga.cgastat &= ~1;
|
||||
|
||||
if (ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1)))
|
||||
ogc->cga.con = 1;
|
||||
if (ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == ((ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
ogc->cga.cursorvisible = 1;
|
||||
}
|
||||
/* 80-columns */
|
||||
if (ogc->cga.cgadispon && (ogc->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (ogc->cga.crtc[1] << 1); x++)
|
||||
ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.ma << 1) + x) & 0x3fff) + ogc->base];
|
||||
if (ogc->cga.cgadispon && (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) {
|
||||
for (x = 0; x < (ogc->cga.crtc[CGA_CRTC_HDISP] << 1); x++)
|
||||
ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.memaddr << 1) + x) & 0x3fff) + ogc->base];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,25 +245,25 @@ t1000_text_row80(t1000_t *t1000)
|
||||
int bold;
|
||||
int blink;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
|
||||
uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff;
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
sc = (t1000->displine) & 7;
|
||||
addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2;
|
||||
ma += (t1000->displine >> 3) * 80;
|
||||
scanline = (t1000->displine) & 7;
|
||||
addr = ((memaddr & ~1) + (t1000->displine >> 3) * 80) * 2;
|
||||
memaddr += (t1000->displine >> 3) * 80;
|
||||
|
||||
if ((t1000->cga.crtc[10] & 0x60) == 0x20) {
|
||||
if ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) {
|
||||
cursorline = 0;
|
||||
} else {
|
||||
cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && ((t1000->cga.crtc[11] & 0x0F) >= sc);
|
||||
cursorline = ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((t1000->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
chr = t1000->vram[(addr + 2 * x) & 0x3FFF];
|
||||
attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t1000->cga.cgablink & 16));
|
||||
|
||||
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (t1000->video_options & 1)
|
||||
bold = boldcols[attr] ? chr : chr + 256;
|
||||
@@ -272,7 +272,7 @@ t1000_text_row80(t1000_t *t1000)
|
||||
if (t1000->video_options & 2)
|
||||
bold += 512;
|
||||
|
||||
if (t1000->cga.cgamode & 0x20) /* Blink */
|
||||
if (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */
|
||||
{
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
@@ -284,13 +284,13 @@ t1000_text_row80(t1000_t *t1000)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
(buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
|
||||
(buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
(buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,25 +306,25 @@ t1000_text_row40(t1000_t *t1000)
|
||||
int bold;
|
||||
int blink;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
|
||||
uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff;
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
sc = (t1000->displine) & 7;
|
||||
addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2;
|
||||
ma += (t1000->displine >> 3) * 40;
|
||||
scanline = (t1000->displine) & 7;
|
||||
addr = ((memaddr & ~1) + (t1000->displine >> 3) * 40) * 2;
|
||||
memaddr += (t1000->displine >> 3) * 40;
|
||||
|
||||
if ((t1000->cga.crtc[10] & 0x60) == 0x20) {
|
||||
if ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) {
|
||||
cursorline = 0;
|
||||
} else {
|
||||
cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && ((t1000->cga.crtc[11] & 0x0F) >= sc);
|
||||
cursorline = ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((t1000->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline);
|
||||
}
|
||||
for (uint8_t x = 0; x < 40; x++) {
|
||||
chr = t1000->vram[(addr + 2 * x) & 0x3FFF];
|
||||
attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t1000->cga.cgablink & 16));
|
||||
|
||||
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (t1000->video_options & 1)
|
||||
bold = boldcols[attr] ? chr : chr + 256;
|
||||
@@ -333,7 +333,7 @@ t1000_text_row40(t1000_t *t1000)
|
||||
if (t1000->video_options & 2)
|
||||
bold += 512;
|
||||
|
||||
if (t1000->cga.cgamode & 0x20) /* Blink */
|
||||
if (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */
|
||||
{
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
@@ -345,14 +345,14 @@ t1000_text_row40(t1000_t *t1000)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
(buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
|
||||
(buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
(buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,9 +366,9 @@ t1000_cgaline6(t1000_t *t1000)
|
||||
uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey;
|
||||
uint32_t bg = grey;
|
||||
|
||||
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
|
||||
uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((memaddr & ~1) << 1);
|
||||
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = t1000->vram[addr & 0x3FFF];
|
||||
@@ -376,7 +376,7 @@ t1000_cgaline6(t1000_t *t1000)
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(t1000->cga.cgamode & 8))
|
||||
if (!(t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE))
|
||||
ink = grey;
|
||||
(buffer32->line[t1000->displine])[x * 8 + c] = ink;
|
||||
dat = dat << 1;
|
||||
@@ -395,8 +395,8 @@ t1000_cgaline4(t1000_t *t1000)
|
||||
uint32_t ink1;
|
||||
uint16_t addr;
|
||||
|
||||
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
|
||||
addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1);
|
||||
uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((memaddr & ~1) << 1);
|
||||
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = t1000->vram[addr & 0x3FFF];
|
||||
@@ -404,7 +404,7 @@ t1000_cgaline4(t1000_t *t1000)
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(t1000->cga.cgamode & 8))
|
||||
if (!(t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
@@ -479,7 +479,7 @@ t1000_poll(void *priv)
|
||||
|
||||
/* Graphics */
|
||||
if (t1000->cga.cgamode & 0x02) {
|
||||
if (t1000->cga.cgamode & 0x10)
|
||||
if (t1000->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
t1000_cgaline6(t1000);
|
||||
else
|
||||
t1000_cgaline4(t1000);
|
||||
@@ -532,7 +532,7 @@ t1000_poll(void *priv)
|
||||
video_res_y = T1000_YSIZE;
|
||||
|
||||
if (t1000->cga.cgamode & 0x02) {
|
||||
if (t1000->cga.cgamode & 0x10)
|
||||
if (t1000->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
@@ -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;
|
||||
|
||||
@@ -254,25 +254,25 @@ t3100e_text_row80(t3100e_t *t3100e)
|
||||
int bold;
|
||||
int blink;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff;
|
||||
uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff;
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
uint16_t cursoraddr = (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
|
||||
sc = (t3100e->displine) & 15;
|
||||
addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2;
|
||||
ma += (t3100e->displine >> 4) * 80;
|
||||
scanline = (t3100e->displine) & 15;
|
||||
addr = ((memaddr & ~1) + (t3100e->displine >> 4) * 80) * 2;
|
||||
memaddr += (t3100e->displine >> 4) * 80;
|
||||
|
||||
if ((t3100e->cga.crtc[10] & 0x60) == 0x20) {
|
||||
if ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) {
|
||||
cursorline = 0;
|
||||
} else {
|
||||
cursorline = ((t3100e->cga.crtc[10] & 0x0F) * 2 <= sc) && ((t3100e->cga.crtc[11] & 0x0F) * 2 >= sc);
|
||||
cursorline = ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) * 2 <= scanline) && ((t3100e->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) * 2 >= scanline);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
chr = t3100e->vram[(addr + 2 * x) & 0x7FFF];
|
||||
attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t3100e->cga.cgablink & 16));
|
||||
|
||||
blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (t3100e->video_options & 4)
|
||||
bold = boldcols[attr] ? chr + 256 : chr;
|
||||
@@ -280,7 +280,7 @@ t3100e_text_row80(t3100e_t *t3100e)
|
||||
bold = boldcols[attr] ? chr : chr + 256;
|
||||
bold += 512 * (t3100e->video_options & 3);
|
||||
|
||||
if (t3100e->cga.cgamode & 0x20) /* Blink */
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */
|
||||
{
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
@@ -292,13 +292,13 @@ t3100e_text_row80(t3100e_t *t3100e)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
(buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
(buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
(buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,25 +315,25 @@ t3100e_text_row40(t3100e_t *t3100e)
|
||||
int bold;
|
||||
int blink;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff;
|
||||
uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff;
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
uint16_t cursoraddr = (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
|
||||
sc = (t3100e->displine) & 15;
|
||||
addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2;
|
||||
ma += (t3100e->displine >> 4) * 40;
|
||||
scanline = (t3100e->displine) & 15;
|
||||
addr = ((memaddr & ~1) + (t3100e->displine >> 4) * 40) * 2;
|
||||
memaddr += (t3100e->displine >> 4) * 40;
|
||||
|
||||
if ((t3100e->cga.crtc[10] & 0x60) == 0x20) {
|
||||
if ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) {
|
||||
cursorline = 0;
|
||||
} else {
|
||||
cursorline = ((t3100e->cga.crtc[10] & 0x0F) * 2 <= sc) && ((t3100e->cga.crtc[11] & 0x0F) * 2 >= sc);
|
||||
cursorline = ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) * 2 <= scanline) && ((t3100e->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) * 2 >= scanline);
|
||||
}
|
||||
for (uint8_t x = 0; x < 40; x++) {
|
||||
chr = t3100e->vram[(addr + 2 * x) & 0x7FFF];
|
||||
attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t3100e->cga.cgablink & 16));
|
||||
|
||||
blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (t3100e->video_options & 4)
|
||||
bold = boldcols[attr] ? chr + 256 : chr;
|
||||
@@ -341,7 +341,7 @@ t3100e_text_row40(t3100e_t *t3100e)
|
||||
bold = boldcols[attr] ? chr : chr + 256;
|
||||
bold += 512 * (t3100e->video_options & 3);
|
||||
|
||||
if (t3100e->cga.cgamode & 0x20) /* Blink */
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */
|
||||
{
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
@@ -353,14 +353,14 @@ t3100e_text_row40(t3100e_t *t3100e)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
(buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
(buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
(buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,13 +374,13 @@ t3100e_cgaline6(t3100e_t *t3100e)
|
||||
uint32_t fg = (t3100e->cga.cgacol & 0x0F) ? amber : black;
|
||||
uint32_t bg = black;
|
||||
|
||||
uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff;
|
||||
uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
|
||||
if (t3100e->cga.crtc[9] == 3) /* 640*400 */
|
||||
if (t3100e->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] == 3) /* 640*400 */
|
||||
{
|
||||
addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
} else {
|
||||
addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = t3100e->vram[addr & 0x7FFF];
|
||||
@@ -388,7 +388,7 @@ t3100e_cgaline6(t3100e_t *t3100e)
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(t3100e->cga.cgamode & 8))
|
||||
if (!(t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE))
|
||||
ink = black;
|
||||
(buffer32->line[t3100e->displine])[x * 8 + c] = ink;
|
||||
dat = dat << 1;
|
||||
@@ -407,13 +407,13 @@ t3100e_cgaline4(t3100e_t *t3100e)
|
||||
uint32_t ink1 = 0;
|
||||
uint16_t addr;
|
||||
|
||||
uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff;
|
||||
if (t3100e->cga.crtc[9] == 3) /* 320*400 undocumented */
|
||||
uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff;
|
||||
if (t3100e->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] == 3) /* 320*400 undocumented */
|
||||
{
|
||||
addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
} else /* 320*200 */
|
||||
{
|
||||
addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = t3100e->vram[addr & 0x7FFF];
|
||||
@@ -421,7 +421,7 @@ t3100e_cgaline4(t3100e_t *t3100e)
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(t3100e->cga.cgamode & 8))
|
||||
if (!(t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
@@ -497,12 +497,12 @@ t3100e_poll(void *priv)
|
||||
}
|
||||
|
||||
/* Graphics */
|
||||
if (t3100e->cga.cgamode & 0x02) {
|
||||
if (t3100e->cga.cgamode & 0x10)
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) {
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
t3100e_cgaline6(t3100e);
|
||||
else
|
||||
t3100e_cgaline4(t3100e);
|
||||
} else if (t3100e->cga.cgamode & 0x01) /* High-res text */
|
||||
} else if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES) /* High-res text */
|
||||
{
|
||||
t3100e_text_row80(t3100e);
|
||||
} else {
|
||||
@@ -550,8 +550,8 @@ t3100e_poll(void *priv)
|
||||
video_res_x = T3100E_XSIZE;
|
||||
video_res_y = T3100E_YSIZE;
|
||||
|
||||
if (t3100e->cga.cgamode & 0x02) {
|
||||
if (t3100e->cga.cgamode & 0x10)
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) {
|
||||
if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
@@ -1098,7 +1098,7 @@ chips_69000_recalctimings(svga_t *svga)
|
||||
svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000);
|
||||
svga->hblank_end_mask = 0xff;
|
||||
|
||||
svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16;
|
||||
svga->memaddr_latch |= (svga->crtc[0x40] & 0xF) << 16;
|
||||
svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8;
|
||||
|
||||
svga->interlace = !!(svga->crtc[0x70] & 0x80);
|
||||
@@ -2044,7 +2044,7 @@ chips_69000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
|
||||
@@ -575,7 +575,7 @@ gd54xx_overlay_draw(svga_t *svga, int displine)
|
||||
uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask];
|
||||
int bpp = svga->bpp;
|
||||
int bytesperpix = (bpp + 7) / 8;
|
||||
uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask];
|
||||
uint8_t *src2 = &svga->vram[(svga->memaddr - (svga->hdisp * bytesperpix)) & svga->vram_display_mask];
|
||||
int occl;
|
||||
int ckval;
|
||||
|
||||
@@ -1255,7 +1255,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) +
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) +
|
||||
((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
@@ -1875,7 +1875,7 @@ gd54xx_recalctimings(svga_t *svga)
|
||||
} else if (svga->gdcreg[5] & 0x40)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
|
||||
svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15);
|
||||
svga->memaddr_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15);
|
||||
|
||||
svga->bpp = 8;
|
||||
|
||||
|
||||
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
* 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 Compaq CGA graphics cards.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: John Elliott, <jce@seasip.info>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2019 John Elliott.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
static uint32_t vflags;
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
typedef struct compaq_cga_t {
|
||||
cga_t cga;
|
||||
} compaq_cga_t;
|
||||
|
||||
#ifdef ENABLE_COMPAQ_CGA_LOG
|
||||
int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG;
|
||||
|
||||
static void
|
||||
compaq_cga_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (compaq_cga_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define compaq_cga_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
void
|
||||
compaq_cga_recalctimings(compaq_cga_t *self)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
disptime = self->cga.crtc[0] + 1;
|
||||
|
||||
_dispontime = self->cga.crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime);
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
void
|
||||
compaq_cga_poll(void *priv)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *) priv;
|
||||
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t border;
|
||||
uint8_t cols[4];
|
||||
int oldsc;
|
||||
int underline = 0;
|
||||
int blink = 0;
|
||||
|
||||
/* If in graphics mode or character height is not 13, behave as CGA */
|
||||
if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) {
|
||||
overscan_x = overscan_y = 16;
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
} else
|
||||
overscan_x = overscan_y = 0;
|
||||
|
||||
/* We are in Compaq 350-line CGA territory */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
oldsc = self->cga.sc;
|
||||
if ((self->cga.crtc[8] & 3) == 3)
|
||||
self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine < self->cga.firstline) {
|
||||
self->cga.firstline = self->cga.displine;
|
||||
video_wait_for_buffer();
|
||||
compaq_cga_log("Firstline %i\n", self->cga.firstline);
|
||||
}
|
||||
self->cga.lastline = self->cga.displine;
|
||||
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][c] = cols[0];
|
||||
if (self->cga.cgamode & 1)
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0];
|
||||
else
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0];
|
||||
}
|
||||
|
||||
if (self->cga.cgamode & 1) {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.charbuffer[x << 1];
|
||||
attr = self->cga.charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
|
||||
if ((self->cga.sc == 12) && ((attr & 7) == 1))
|
||||
underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
self->cga.ma++;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.vram[(self->cga.ma << 1) & 0x3fff];
|
||||
attr = self->cga.vram[((self->cga.ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
if (self->cga.sc == 12 && (attr & 7) == 1)
|
||||
underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
self->cga.ma++;
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
|
||||
if (self->cga.cgamode & 1)
|
||||
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]);
|
||||
else
|
||||
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (self->cga.cgamode & 1)
|
||||
x = (self->cga.crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (self->cga.crtc[1] << 4) + 16;
|
||||
|
||||
if (self->cga.composite) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = self->cga.cgacol & 0x0f;
|
||||
|
||||
if (vflags)
|
||||
Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
else
|
||||
Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
} else
|
||||
video_process_8(x, self->cga.displine);
|
||||
|
||||
self->cga.sc = oldsc;
|
||||
if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc)
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.displine++;
|
||||
if (self->cga.displine >= 500)
|
||||
self->cga.displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
self->cga.linepos = 0;
|
||||
if (self->cga.vsynctime) {
|
||||
self->cga.vsynctime--;
|
||||
if (!self->cga.vsynctime)
|
||||
self->cga.cgastat &= ~8;
|
||||
}
|
||||
|
||||
if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) {
|
||||
self->cga.con = 0;
|
||||
self->cga.coff = 1;
|
||||
}
|
||||
if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1))
|
||||
self->cga.maback = self->cga.ma;
|
||||
if (self->cga.vadj) {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
self->cga.vadj--;
|
||||
if (!self->cga.vadj) {
|
||||
self->cga.cgadispon = 1;
|
||||
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
self->cga.sc = 0;
|
||||
}
|
||||
} else if (self->cga.sc == self->cga.crtc[9]) {
|
||||
self->cga.maback = self->cga.ma;
|
||||
self->cga.sc = 0;
|
||||
oldvc = self->cga.vc;
|
||||
self->cga.vc++;
|
||||
self->cga.vc &= 127;
|
||||
|
||||
if (self->cga.vc == self->cga.crtc[6])
|
||||
self->cga.cgadispon = 0;
|
||||
|
||||
if (oldvc == self->cga.crtc[4]) {
|
||||
self->cga.vc = 0;
|
||||
self->cga.vadj = self->cga.crtc[5];
|
||||
|
||||
if (!self->cga.vadj)
|
||||
self->cga.cgadispon = 1;
|
||||
|
||||
if (!self->cga.vadj)
|
||||
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
|
||||
if ((self->cga.crtc[10] & 0x60) == 0x20)
|
||||
self->cga.cursoron = 0;
|
||||
else
|
||||
self->cga.cursoron = self->cga.cgablink & 8;
|
||||
}
|
||||
|
||||
if (self->cga.vc == self->cga.crtc[7]) {
|
||||
self->cga.cgadispon = 0;
|
||||
self->cga.displine = 0;
|
||||
self->cga.vsynctime = 16;
|
||||
|
||||
if (self->cga.crtc[7]) {
|
||||
compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline,
|
||||
self->cga.firstline, self->cga.lastline - self->cga.firstline);
|
||||
|
||||
if (self->cga.cgamode & 1)
|
||||
x = (self->cga.crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (self->cga.crtc[1] << 4) + 16;
|
||||
|
||||
self->cga.lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (self->cga.lastline - self->cga.firstline);
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan)
|
||||
video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
|
||||
else
|
||||
video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
|
||||
}
|
||||
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
if (enable_overscan)
|
||||
xsize -= 16;
|
||||
video_res_y = ysize;
|
||||
if (self->cga.cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
|
||||
self->cga.firstline = 1000;
|
||||
self->cga.lastline = 0;
|
||||
self->cga.cgablink++;
|
||||
self->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
}
|
||||
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
if (self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))
|
||||
self->cga.con = 1;
|
||||
|
||||
if (self->cga.cgadispon && (self->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (self->cga.crtc[1] << 1); x++)
|
||||
self->cga.charbuffer[x] = self->cga.vram[((self->cga.ma << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
compaq_cga_init(const device_t *info)
|
||||
{
|
||||
int display_type;
|
||||
compaq_cga_t *self = malloc(sizeof(compaq_cga_t));
|
||||
memset(self, 0, sizeof(compaq_cga_t));
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
self->cga.composite = (display_type != CGA_RGB);
|
||||
self->cga.revision = device_get_config_int("composite_type");
|
||||
self->cga.snow_enabled = device_get_config_int("snow_enabled");
|
||||
|
||||
self->cga.vram = malloc(0x4000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_add(&self->cga.timer, compaq_cga_poll, self, 1);
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self);
|
||||
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self);
|
||||
|
||||
if (info->local) {
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
vflags = info->local;
|
||||
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
|
||||
self->cga.crtc[9] = 13;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
compaq_cga_close(void *priv)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void
|
||||
compaq_cga_speed_changed(void *priv)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *) priv;
|
||||
|
||||
if (self->cga.crtc[9] == 13) /* Character height */
|
||||
compaq_cga_recalctimings(self);
|
||||
else
|
||||
cga_recalctimings(&self->cga);
|
||||
}
|
||||
|
||||
extern const device_config_t cga_config[];
|
||||
|
||||
const device_t compaq_cga_device = {
|
||||
.name = "Compaq CGA",
|
||||
.internal_name = "compaq_cga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
const device_t compaq_cga_2_device = {
|
||||
.name = "Compaq CGA 2",
|
||||
.internal_name = "compaq_cga_2",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
@@ -313,7 +313,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if ((idx < 0xe) || (idx > 0x10)) {
|
||||
if ((idx == 0xc) || (idx == 0xd)) {
|
||||
ega->fullchange = 3;
|
||||
ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) +
|
||||
ega->memaddr_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) +
|
||||
((ega->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
ega->fullchange = changeframecount;
|
||||
@@ -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:
|
||||
@@ -649,7 +649,7 @@ ega_recalctimings(ega_t *ega)
|
||||
|
||||
ega->interlace = 0;
|
||||
|
||||
ega->ma_latch = (ega->crtc[0xc] << 8) | ega->crtc[0xd];
|
||||
ega->memaddr_latch = (ega->crtc[0xc] << 8) | ega->crtc[0xd];
|
||||
|
||||
ega->render = ega_render_blank;
|
||||
if (!ega->scrblank && ega->attr_palette_enable) {
|
||||
@@ -748,7 +748,7 @@ ega_dot_poll(void *priv)
|
||||
const int dwshift = doublewidth ? 1 : 0;
|
||||
const int dotwidth = 1 << dwshift;
|
||||
const int charwidth = dotwidth * (seq9dot ? 9 : 8);
|
||||
const int cursoron = (ega->sc == (ega->crtc[10] & 31));
|
||||
const int cursoron = (ega->scanline == (ega->crtc[10] & 31));
|
||||
const int cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
|
||||
uint32_t addr;
|
||||
int drawcursor;
|
||||
@@ -792,7 +792,7 @@ ega_dot_poll(void *priv)
|
||||
else
|
||||
charaddr = ega->charseta + (chr * 0x80);
|
||||
|
||||
dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
dat = ega->vram[charaddr + (ega->scanline << 2)];
|
||||
dat <<= 1;
|
||||
if ((chr & ~0x1F) == 0xC0 && attrlinechars)
|
||||
dat |= (dat >> 1) & 1;
|
||||
@@ -837,19 +837,19 @@ 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) {
|
||||
ega->hdisp_on = 1;
|
||||
|
||||
ega->ma &= ega->vrammask;
|
||||
ega->memaddr &= ega->vrammask;
|
||||
if (ega->firstline == 2000) {
|
||||
ega->firstline = ega->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
|
||||
old_ma = ega->ma;
|
||||
old_ma = ega->memaddr;
|
||||
ega->displine *= ega->vres + 1;
|
||||
ega->y_add *= ega->vres + 1;
|
||||
for (int y = 0; y <= ega->vres; y++) {
|
||||
@@ -863,7 +863,7 @@ ega_poll(void *priv)
|
||||
ega->x_add = (overscan_x >> 1) - ega->scrollcache;
|
||||
|
||||
if (y != ega->vres) {
|
||||
ega->ma = old_ma;
|
||||
ega->memaddr = old_ma;
|
||||
ega->displine++;
|
||||
}
|
||||
}
|
||||
@@ -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,35 +896,35 @@ 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;
|
||||
if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount))
|
||||
ega->con = 0;
|
||||
if ((ega->scanline == (ega->crtc[11] & 31)) || (ega->scanline == ega->rowcount))
|
||||
ega->cursorvisible = 0;
|
||||
if (ega->dispon) {
|
||||
/* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll */
|
||||
if (ega->linedbl && !ega->linecountff) {
|
||||
ega->linecountff = 1;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
ega->memaddr = ega->memaddr_backup;
|
||||
ega->cca = ega->memaddr_backup;
|
||||
}
|
||||
if (ega->sc == (ega->crtc[9] & 31)) {
|
||||
if (ega->scanline == (ega->crtc[9] & 31)) {
|
||||
ega->linecountff = 0;
|
||||
ega->sc = 0;
|
||||
ega->scanline = 0;
|
||||
|
||||
ega->maback += (ega->rowoffset << 3);
|
||||
ega->memaddr_backup += (ega->rowoffset << 3);
|
||||
if (ega->interlace)
|
||||
ega->maback += (ega->rowoffset << 3);
|
||||
ega->maback &= ega->vrammask;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
ega->memaddr_backup += (ega->rowoffset << 3);
|
||||
ega->memaddr_backup &= ega->vrammask;
|
||||
ega->memaddr = ega->memaddr_backup;
|
||||
ega->cca = ega->memaddr_backup;
|
||||
} else {
|
||||
ega->linecountff = 0;
|
||||
ega->sc++;
|
||||
ega->sc &= 31;
|
||||
ega->ma = ega->maback;
|
||||
ega->cca = ega->maback;
|
||||
ega->scanline++;
|
||||
ega->scanline &= 31;
|
||||
ega->memaddr = ega->memaddr_backup;
|
||||
ega->cca = ega->memaddr_backup;
|
||||
}
|
||||
}
|
||||
ega->real_vc++;
|
||||
@@ -941,13 +941,13 @@ ega_poll(void *priv)
|
||||
if (ega->vc == ega->split) {
|
||||
// TODO: Implement the hardware bug where the first scanline is drawn twice when the split happens
|
||||
if (ega->interlace && ega->oddeven)
|
||||
ega->ma = ega->maback = ega->rowoffset << 1;
|
||||
ega->memaddr = ega->memaddr_backup = ega->rowoffset << 1;
|
||||
else
|
||||
ega->ma = ega->maback = 0;
|
||||
ega->ma <<= 2;
|
||||
ega->cca = ega->ma;
|
||||
ega->maback <<= 2;
|
||||
ega->sc = 0;
|
||||
ega->memaddr = ega->memaddr_backup = 0;
|
||||
ega->memaddr <<= 2;
|
||||
ega->cca = ega->memaddr;
|
||||
ega->memaddr_backup <<= 2;
|
||||
ega->scanline = 0;
|
||||
}
|
||||
if (ega->vc == ega->dispend) {
|
||||
ega->dispon = 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
|
||||
@@ -1007,19 +1007,19 @@ ega_poll(void *priv)
|
||||
ega->vslines = 0;
|
||||
|
||||
if (ega->interlace && ega->oddeven)
|
||||
ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1);
|
||||
ega->memaddr = ega->memaddr_backup = ega->memaddr_latch + (ega->rowoffset << 1);
|
||||
else
|
||||
ega->ma = ega->maback = ega->ma_latch;
|
||||
ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
|
||||
ega->memaddr = ega->memaddr_backup = ega->memaddr_latch;
|
||||
ega->cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
|
||||
|
||||
ega->ma <<= 2;
|
||||
ega->maback <<= 2;
|
||||
ega->ca <<= 2;
|
||||
ega->cca = ega->ma;
|
||||
ega->memaddr <<= 2;
|
||||
ega->memaddr_backup <<= 2;
|
||||
ega->cursoraddr <<= 2;
|
||||
ega->cca = ega->memaddr;
|
||||
}
|
||||
if (ega->vc == ega->vtotal) {
|
||||
ega->vc = 0;
|
||||
ega->sc = (ega->crtc[0x8] & 0x1f);
|
||||
ega->scanline = (ega->crtc[0x8] & 0x1f);
|
||||
ega->dispon = 1;
|
||||
ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0;
|
||||
|
||||
@@ -1036,8 +1036,8 @@ ega_poll(void *priv)
|
||||
|
||||
ega->linecountff = 0;
|
||||
}
|
||||
if (ega->sc == (ega->crtc[10] & 31))
|
||||
ega->con = 1;
|
||||
if (ega->scanline == (ega->crtc[10] & 31))
|
||||
ega->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1512,24 +1512,24 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
|
||||
ega->pallook = pallook16;
|
||||
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
ega->mdacols[c][0][0] = ega->mdacols[c][1][0] = ega->mdacols[c][1][1] = 16;
|
||||
ega->mda_attr_to_color_table[c][0][0] = ega->mda_attr_to_color_table[c][1][0] = ega->mda_attr_to_color_table[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
ega->mdacols[c][0][1] = 15 + 16;
|
||||
ega->mda_attr_to_color_table[c][0][1] = 15 + 16;
|
||||
else
|
||||
ega->mdacols[c][0][1] = 7 + 16;
|
||||
ega->mda_attr_to_color_table[c][0][1] = 7 + 16;
|
||||
}
|
||||
ega->mdacols[0x70][0][1] = 16;
|
||||
ega->mdacols[0x70][0][0] = ega->mdacols[0x70][1][0] = ega->mdacols[0x70][1][1] = 16 + 15;
|
||||
ega->mdacols[0xF0][0][1] = 16;
|
||||
ega->mdacols[0xF0][0][0] = ega->mdacols[0xF0][1][0] = ega->mdacols[0xF0][1][1] = 16 + 15;
|
||||
ega->mdacols[0x78][0][1] = 16 + 7;
|
||||
ega->mdacols[0x78][0][0] = ega->mdacols[0x78][1][0] = ega->mdacols[0x78][1][1] = 16 + 15;
|
||||
ega->mdacols[0xF8][0][1] = 16 + 7;
|
||||
ega->mdacols[0xF8][0][0] = ega->mdacols[0xF8][1][0] = ega->mdacols[0xF8][1][1] = 16 + 15;
|
||||
ega->mdacols[0x00][0][1] = ega->mdacols[0x00][1][1] = 16;
|
||||
ega->mdacols[0x08][0][1] = ega->mdacols[0x08][1][1] = 16;
|
||||
ega->mdacols[0x80][0][1] = ega->mdacols[0x80][1][1] = 16;
|
||||
ega->mdacols[0x88][0][1] = ega->mdacols[0x88][1][1] = 16;
|
||||
ega->mda_attr_to_color_table[0x70][0][1] = 16;
|
||||
ega->mda_attr_to_color_table[0x70][0][0] = ega->mda_attr_to_color_table[0x70][1][0] = ega->mda_attr_to_color_table[0x70][1][1] = 16 + 15;
|
||||
ega->mda_attr_to_color_table[0xF0][0][1] = 16;
|
||||
ega->mda_attr_to_color_table[0xF0][0][0] = ega->mda_attr_to_color_table[0xF0][1][0] = ega->mda_attr_to_color_table[0xF0][1][1] = 16 + 15;
|
||||
ega->mda_attr_to_color_table[0x78][0][1] = 16 + 7;
|
||||
ega->mda_attr_to_color_table[0x78][0][0] = ega->mda_attr_to_color_table[0x78][1][0] = ega->mda_attr_to_color_table[0x78][1][1] = 16 + 15;
|
||||
ega->mda_attr_to_color_table[0xF8][0][1] = 16 + 7;
|
||||
ega->mda_attr_to_color_table[0xF8][0][0] = ega->mda_attr_to_color_table[0xF8][1][0] = ega->mda_attr_to_color_table[0xF8][1][1] = 16 + 15;
|
||||
ega->mda_attr_to_color_table[0x00][0][1] = ega->mda_attr_to_color_table[0x00][1][1] = 16;
|
||||
ega->mda_attr_to_color_table[0x08][0][1] = ega->mda_attr_to_color_table[0x08][1][1] = 16;
|
||||
ega->mda_attr_to_color_table[0x80][0][1] = ega->mda_attr_to_color_table[0x80][1][1] = 16;
|
||||
ega->mda_attr_to_color_table[0x88][0][1] = ega->mda_attr_to_color_table[0x88][1][1] = 16;
|
||||
|
||||
egaswitches = monitor_type & 0xf;
|
||||
|
||||
|
||||
@@ -141,9 +141,9 @@ ega_render_text(ega_t *ega)
|
||||
}
|
||||
|
||||
for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) {
|
||||
uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask;
|
||||
uint32_t addr = ega->remap_func(ega, ega->memaddr) & ega->vrammask;
|
||||
|
||||
int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
|
||||
int drawcursor = ((ega->memaddr == ega->cursoraddr) && ega->cursorvisible && ega->cursoron);
|
||||
|
||||
uint32_t chr;
|
||||
uint32_t attr;
|
||||
@@ -175,7 +175,7 @@ ega_render_text(ega_t *ega)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
uint32_t dat = ega->vram[charaddr + (ega->scanline << 2)];
|
||||
dat <<= 1;
|
||||
if (((chr & ~0x1f) == 0xc0) && attrlinechars)
|
||||
dat |= (dat >> 1) & 1;
|
||||
@@ -184,21 +184,21 @@ ega_render_text(ega_t *ega)
|
||||
if (monoattrs) {
|
||||
int bit = (dat & (0x100 >> (xx >> dwshift))) ? 1 : 0;
|
||||
int blink = (!drawcursor && (attr & 0x80) && attrblink && blinked);
|
||||
if ((ega->sc == ega->crtc[0x14]) && ((attr & 7) == 1))
|
||||
p[xx] = ega->mdacols[attr][blink][1];
|
||||
if ((ega->scanline == ega->crtc[0x14]) && ((attr & 7) == 1))
|
||||
p[xx] = ega->mda_attr_to_color_table[attr][blink][1];
|
||||
else
|
||||
p[xx] = ega->mdacols[attr][blink][bit];
|
||||
p[xx] = ega->mda_attr_to_color_table[attr][blink][bit];
|
||||
if (drawcursor)
|
||||
p[xx] ^= ega->mdacols[attr][0][1];
|
||||
p[xx] ^= ega->mda_attr_to_color_table[attr][0][1];
|
||||
p[xx] = ega->pallook[ega->egapal[p[xx] & 0x0f]];
|
||||
} else
|
||||
p[xx] = (dat & (0x100 >> (xx >> dwshift))) ? fg : bg;
|
||||
}
|
||||
|
||||
ega->ma += 4;
|
||||
ega->memaddr += 4;
|
||||
p += charwidth;
|
||||
}
|
||||
ega->ma &= 0x3ffff;
|
||||
ega->memaddr &= 0x3ffff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ ega_render_graphics(ega_t *ega)
|
||||
}
|
||||
|
||||
for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) {
|
||||
uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask;
|
||||
uint32_t addr = ega->remap_func(ega, ega->memaddr) & ega->vrammask;
|
||||
|
||||
uint8_t edat[4];
|
||||
if (seqoddeven) {
|
||||
@@ -247,12 +247,12 @@ ega_render_graphics(ega_t *ega)
|
||||
edat[3] = ega->vram[(addr | 3) ^ secondcclk];
|
||||
secondcclk = (secondcclk + 1) & 1;
|
||||
if (secondcclk == 0)
|
||||
ega->ma += 4;
|
||||
ega->memaddr += 4;
|
||||
} else {
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]);
|
||||
ega->ma += 4;
|
||||
ega->memaddr += 4;
|
||||
}
|
||||
ega->ma &= 0x3ffff;
|
||||
ega->memaddr &= 0x3ffff;
|
||||
|
||||
if (cga2bpp) {
|
||||
// Remap CGA 2bpp-chunky data into fully planar data
|
||||
|
||||
@@ -424,7 +424,7 @@ et3000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
static void
|
||||
et3000_recalctimings(svga_t *svga)
|
||||
{
|
||||
svga->ma_latch |= (svga->crtc[0x23] & 2) << 15;
|
||||
svga->memaddr_latch |= (svga->crtc[0x23] & 2) << 15;
|
||||
if (svga->crtc[0x25] & 1)
|
||||
svga->vblankstart |= 0x400;
|
||||
if (svga->crtc[0x25] & 2)
|
||||
@@ -439,7 +439,7 @@ et3000_recalctimings(svga_t *svga)
|
||||
svga->interlace = !!(svga->crtc[0x25] & 0x80);
|
||||
|
||||
if (svga->attrregs[0x16] & 0x10) {
|
||||
svga->ma_latch <<= (1 << 0);
|
||||
svga->memaddr_latch <<= (1 << 0);
|
||||
svga->rowoffset <<= (1 << 0);
|
||||
switch (svga->gdcreg[5] & 0x60) {
|
||||
case 0x00:
|
||||
|
||||
@@ -378,7 +378,7 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -642,7 +642,7 @@ et4000_recalctimings(svga_t *svga)
|
||||
{
|
||||
const et4000_t *dev = (et4000_t *) svga->priv;
|
||||
|
||||
svga->ma_latch |= (svga->crtc[0x33] & 3) << 16;
|
||||
svga->memaddr_latch |= (svga->crtc[0x33] & 3) << 16;
|
||||
|
||||
svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2];
|
||||
|
||||
@@ -701,7 +701,7 @@ et4000_recalctimings(svga_t *svga)
|
||||
if (dev->type == ET4000_TYPE_KOREAN || dev->type == ET4000_TYPE_TRIGEM || dev->type == ET4000_TYPE_KASAN) {
|
||||
if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) {
|
||||
if (dev->port_32cb_val & 0x80) {
|
||||
svga->ma_latch -= 2;
|
||||
svga->memaddr_latch -= 2;
|
||||
svga->ca_adj = -2;
|
||||
}
|
||||
if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) {
|
||||
@@ -719,7 +719,7 @@ et4000_recalctimings(svga_t *svga)
|
||||
}
|
||||
|
||||
if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40) && svga->lowres) {
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
@@ -734,7 +734,7 @@ et4000_kasan_recalctimings(svga_t *svga)
|
||||
|
||||
if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) {
|
||||
svga->hdisp += svga->dots_per_clock;
|
||||
svga->ma_latch -= 4;
|
||||
svga->memaddr_latch -= 4;
|
||||
svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3;
|
||||
svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5;
|
||||
if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A))
|
||||
|
||||
@@ -238,7 +238,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -430,7 +430,7 @@ et4000w32p_recalctimings(svga_t *svga)
|
||||
{
|
||||
et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv;
|
||||
|
||||
svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16;
|
||||
svga->memaddr_latch |= (svga->crtc[0x33] & 0x7) << 16;
|
||||
|
||||
svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2];
|
||||
|
||||
|
||||
@@ -361,28 +361,28 @@ f82c425_text_row(f82c425_t *f82c425)
|
||||
int cursorline;
|
||||
int blink;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff;
|
||||
uint16_t ca = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff;
|
||||
uint8_t sl = f82c425->cga.crtc[9] + 1;
|
||||
int columns = f82c425->cga.crtc[1];
|
||||
uint8_t scanline;
|
||||
uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff;
|
||||
uint8_t sl = f82c425->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
|
||||
int columns = f82c425->cga.crtc[CGA_CRTC_HDISP];
|
||||
|
||||
sc = (f82c425->displine) & 7;
|
||||
addr = ((ma & ~1) + (f82c425->displine >> 3) * columns) * 2;
|
||||
ma += (f82c425->displine >> 3) * columns;
|
||||
scanline = (f82c425->displine) & 7;
|
||||
addr = ((memaddr & ~1) + (f82c425->displine >> 3) * columns) * 2;
|
||||
memaddr += (f82c425->displine >> 3) * columns;
|
||||
|
||||
if ((f82c425->cga.crtc[0x0a] & 0x60) == 0x20) {
|
||||
if ((f82c425->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) {
|
||||
cursorline = 0;
|
||||
} else {
|
||||
cursorline = ((f82c425->cga.crtc[0x0a] & 0x0F) <= sc) && ((f82c425->cga.crtc[0x0b] & 0x0F) >= sc);
|
||||
cursorline = ((f82c425->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((f82c425->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline);
|
||||
}
|
||||
|
||||
for (int x = 0; x < columns; x++) {
|
||||
chr = f82c425->vram[(addr + 2 * x) & 0x3FFF];
|
||||
attr = f82c425->vram[(addr + 2 * x + 1) & 0x3FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (f82c425->cga.cgamode & 0x8) && (f82c425->cga.cgablink & 0x10));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && (f82c425->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (f82c425->cga.cgablink & 0x10));
|
||||
|
||||
blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (drawcursor) {
|
||||
colors[0] = smartmap[~attr & 0xff][0];
|
||||
@@ -398,16 +398,16 @@ f82c425_text_row(f82c425_t *f82c425)
|
||||
if (f82c425->cga.cgamode & 0x01) {
|
||||
/* High resolution (80 cols) */
|
||||
for (c = 0; c < sl; c++) {
|
||||
(buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
} else {
|
||||
/* Low resolution (40 columns, stretch pixels horizontally) */
|
||||
for (c = 0; c < sl; c++) {
|
||||
(buffer32->line[f82c425->displine])[(x << 4) + c * 2] = (buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
(buffer32->line[f82c425->displine])[(x << 4) + c * 2] = (buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,9 +418,9 @@ f82c425_cgaline6(f82c425_t *f82c425)
|
||||
uint8_t dat;
|
||||
uint16_t addr;
|
||||
|
||||
uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff;
|
||||
uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1);
|
||||
addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((memaddr & ~1) << 1);
|
||||
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = f82c425->vram[addr & 0x3FFF];
|
||||
@@ -442,8 +442,8 @@ f82c425_cgaline4(f82c425_t *f82c425)
|
||||
uint8_t pattern;
|
||||
uint16_t addr;
|
||||
|
||||
uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff;
|
||||
addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1);
|
||||
uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((memaddr & ~1) << 1);
|
||||
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = f82c425->vram[addr & 0x3FFF];
|
||||
@@ -526,7 +526,7 @@ f82c425_poll(void *priv)
|
||||
f82c425->displine = 0;
|
||||
f82c425->cga.cgastat &= ~8;
|
||||
f82c425->dispon = 1;
|
||||
} else if (f82c425->displine == (f82c425->cga.crtc[9] + 1) * f82c425->cga.crtc[6]) {
|
||||
} else if (f82c425->displine == (f82c425->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * f82c425->cga.crtc[CGA_CRTC_VDISP]) {
|
||||
/* Start of VSYNC */
|
||||
f82c425->cga.cgastat |= 8;
|
||||
f82c425->dispon = 0;
|
||||
|
||||
@@ -387,7 +387,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
int cw = 9; /* Each character is 9 pixels wide */
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t sc;
|
||||
uint8_t scanline;
|
||||
uint8_t ctrl;
|
||||
const uint8_t *crtc;
|
||||
uint8_t bitmap[2];
|
||||
@@ -398,8 +398,8 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
int drawcursor;
|
||||
int cursorline;
|
||||
uint16_t addr;
|
||||
uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff;
|
||||
uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t memaddr = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff;
|
||||
const uint8_t *framebuf = genius->vram + 0x10000;
|
||||
uint32_t col;
|
||||
uint32_t dl = genius->displine;
|
||||
@@ -416,14 +416,14 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
#if 0
|
||||
if (genius->genius_charh & 0x10) {
|
||||
row = ((dl >> 1) / charh);
|
||||
sc = ((dl >> 1) % charh);
|
||||
scanline = ((dl >> 1) % charh);
|
||||
} else {
|
||||
row = (dl / charh);
|
||||
sc = (dl % charh);
|
||||
scanline = (dl % charh);
|
||||
}
|
||||
#else
|
||||
row = (dl / charh);
|
||||
sc = (dl % charh);
|
||||
scanline = (dl % charh);
|
||||
#endif
|
||||
} else {
|
||||
if ((genius->displine < 512) || (genius->displine >= 912))
|
||||
@@ -439,23 +439,23 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
charh = crtc[9] + 1;
|
||||
|
||||
row = ((dl >> 1) / charh);
|
||||
sc = ((dl >> 1) % charh);
|
||||
scanline = ((dl >> 1) % charh);
|
||||
}
|
||||
|
||||
ma = (crtc[13] | (crtc[12] << 8)) & 0x3fff;
|
||||
ca = (crtc[15] | (crtc[14] << 8)) & 0x3fff;
|
||||
memaddr = (crtc[13] | (crtc[12] << 8)) & 0x3fff;
|
||||
cursoraddr = (crtc[15] | (crtc[14] << 8)) & 0x3fff;
|
||||
|
||||
addr = ((ma & ~1) + row * w) * 2;
|
||||
addr = ((memaddr & ~1) + row * w) * 2;
|
||||
|
||||
if (!mda)
|
||||
dl += 512;
|
||||
|
||||
ma += (row * w);
|
||||
memaddr += (row * w);
|
||||
|
||||
if ((crtc[10] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = ((crtc[10] & 0x1F) <= sc) && ((crtc[11] & 0x1F) >= sc);
|
||||
cursorline = ((crtc[10] & 0x1F) <= scanline) && ((crtc[11] & 0x1F) >= scanline);
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
#if 0
|
||||
@@ -467,7 +467,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
chr = framebuf[(addr + 2 * x) & 0x3FFF];
|
||||
attr = framebuf[(addr + 2 * x + 1) & 0x3FFF];
|
||||
|
||||
drawcursor = ((ma == ca) && cursorline && genius->enabled && (ctrl & 8));
|
||||
drawcursor = ((memaddr == cursoraddr) && cursorline && genius->enabled && (ctrl & 8));
|
||||
|
||||
switch (crtc[10] & 0x60) {
|
||||
case 0x00:
|
||||
@@ -487,7 +487,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
attr &= 0x7F;
|
||||
|
||||
/* MDA underline */
|
||||
if (mda && (sc == charh) && ((attr & 7) == 1)) {
|
||||
if (mda && (scanline == charh) && ((attr & 7) == 1)) {
|
||||
col = mdaattr[attr][blink][1];
|
||||
|
||||
if (genius->genius_control & 0x20)
|
||||
@@ -504,9 +504,9 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
}
|
||||
} else { /* Draw 8 pixels of character */
|
||||
if (mda)
|
||||
bitmap[0] = fontdat8x12[chr][sc];
|
||||
bitmap[0] = fontdat8x12[chr][scanline];
|
||||
else
|
||||
bitmap[0] = fontdat[chr][sc];
|
||||
bitmap[0] = fontdat[chr][scanline];
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
col = mdaattr[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
@@ -563,7 +563,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80)
|
||||
}
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
++memaddr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,9 +168,9 @@ hercules_in(uint16_t addr, void *priv)
|
||||
case 0x03b5:
|
||||
case 0x03b7:
|
||||
if (dev->crtcreg == 0x0c)
|
||||
ret = (dev->ma >> 8) & 0x3f;
|
||||
ret = (dev->memaddr >> 8) & 0x3f;
|
||||
else if (dev->crtcreg == 0x0d)
|
||||
ret = dev->ma & 0xff;
|
||||
ret = dev->memaddr & 0xff;
|
||||
else
|
||||
ret = dev->crtc[dev->crtcreg];
|
||||
break;
|
||||
@@ -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;
|
||||
@@ -281,10 +281,10 @@ hercules_poll(void *priv)
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t ca;
|
||||
uint16_t cursoraddr;
|
||||
uint16_t dat;
|
||||
uint16_t pa;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int blink;
|
||||
int x;
|
||||
int xx;
|
||||
@@ -296,16 +296,16 @@ hercules_poll(void *priv)
|
||||
uint32_t *p;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
|
||||
if (!dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
dev->status |= 1;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
scanline_old = dev->scanline;
|
||||
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = (dev->sc << 1) & 7;
|
||||
dev->scanline = (dev->scanline << 1) & 7;
|
||||
|
||||
if (dev->dispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
@@ -317,16 +317,16 @@ hercules_poll(void *priv)
|
||||
hercules_render_overscan_left(dev);
|
||||
|
||||
if (dev->ctrl & 0x02) {
|
||||
ca = (dev->sc & 3) * 0x2000;
|
||||
cursoraddr = (dev->scanline & 3) * 0x2000;
|
||||
if (dev->ctrl & 0x80)
|
||||
ca += 0x8000;
|
||||
cursoraddr += 0x8000;
|
||||
|
||||
for (x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8)
|
||||
dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1];
|
||||
dat = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr] << 8) | dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 1];
|
||||
else
|
||||
dat = 0;
|
||||
dev->ma++;
|
||||
dev->memaddr++;
|
||||
for (c = 0; c < 16; c++)
|
||||
buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0;
|
||||
for (c = 0; c < 16; c += 8)
|
||||
@@ -341,25 +341,25 @@ hercules_poll(void *priv)
|
||||
attr = dev->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
|
||||
drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron);
|
||||
blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (dev->sc == 12 && ((attr & 7) == 1)) {
|
||||
if (dev->scanline == 12 && ((attr & 7) == 1)) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
|
||||
if ((chr & ~0x1f) == 0xc0)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1];
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->scanline] & 1];
|
||||
else
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0];
|
||||
}
|
||||
if (dev->ctrl2 & 0x01)
|
||||
dev->ma = (dev->ma + 1) & 0x3fff;
|
||||
dev->memaddr = (dev->memaddr + 1) & 0x3fff;
|
||||
else
|
||||
dev->ma = (dev->ma + 1) & 0x7ff;
|
||||
dev->memaddr = (dev->memaddr + 1) & 0x7ff;
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 9; c++)
|
||||
@@ -377,10 +377,10 @@ hercules_poll(void *priv)
|
||||
|
||||
video_process_8(x + 16, dev->displine + 14);
|
||||
}
|
||||
dev->sc = oldsc;
|
||||
dev->scanline = scanline_old;
|
||||
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->stat |= 8;
|
||||
if (dev->vc == dev->crtc[7] && !dev->scanline)
|
||||
dev->status |= 8;
|
||||
dev->displine++;
|
||||
if (dev->displine >= 500)
|
||||
dev->displine = 0;
|
||||
@@ -388,33 +388,32 @@ 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->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->cursorvisible = 0;
|
||||
}
|
||||
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->scanline = 0;
|
||||
}
|
||||
} else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
} else if (((dev->crtc[8] & 3) != 3 && dev->scanline == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) {
|
||||
dev->memaddr_backup = dev->memaddr;
|
||||
dev->scanline = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
@@ -427,7 +426,7 @@ hercules_poll(void *priv)
|
||||
dev->vadj = dev->crtc[5];
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (dev->crtc[10] & 0x60) {
|
||||
case 0x20:
|
||||
@@ -512,17 +511,17 @@ hercules_poll(void *priv)
|
||||
dev->blink++;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
}
|
||||
|
||||
if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->con = 1;
|
||||
if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->cursorvisible = 1;
|
||||
if (dev->dispon && !(dev->ctrl & 0x02)) {
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000;
|
||||
dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa];
|
||||
dev->charbuffer[x] = dev->vram[(((dev->memaddr << 1) + x) & 0x3fff) + pa];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -165,9 +165,9 @@ typedef struct {
|
||||
int firstline, lastline;
|
||||
|
||||
int linepos, displine;
|
||||
int vc, sc;
|
||||
uint16_t ma, maback;
|
||||
int con, coff, cursoron;
|
||||
int vc, scanline;
|
||||
uint16_t memaddr, memaddr_backup;
|
||||
int cursorvisible, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
@@ -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:
|
||||
@@ -483,11 +483,11 @@ draw_char_rom(incolor_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
}
|
||||
|
||||
fnt = &(fontdatm[chr][dev->sc]);
|
||||
fnt = &(fontdatm[chr][dev->scanline]);
|
||||
|
||||
if (blk) {
|
||||
val = 0x000; /* Blinking, draw all background */
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
val = 0x1ff; /* Underscore, draw all foreground */
|
||||
} else {
|
||||
val = fnt[0] << 1;
|
||||
@@ -559,12 +559,12 @@ draw_char_ram4(incolor_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
} else {
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
}
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + dev->sc;
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + dev->scanline;
|
||||
|
||||
if (blk) {
|
||||
/* Blinking, draw all background */
|
||||
val[0] = val[1] = val[2] = val[3] = 0x000;
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
/* Underscore, draw all foreground */
|
||||
val[0] = val[1] = val[2] = val[3] = 0x1ff;
|
||||
} else {
|
||||
@@ -685,12 +685,12 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
} else {
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
}
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc;
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->scanline;
|
||||
|
||||
if (blk) {
|
||||
/* Blinking, draw all background */
|
||||
val[0] = val[1] = val[2] = val[3] = 0x000;
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
/* Underscore, draw all foreground */
|
||||
val[0] = val[1] = val[2] = val[3] = 0x1ff;
|
||||
} else {
|
||||
@@ -716,9 +716,9 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
/* Generate pixel colour */
|
||||
cfg = 0;
|
||||
pmask = 1;
|
||||
if (dev->sc == oll) {
|
||||
if (dev->scanline == oll) {
|
||||
cfg = olc ^ ibg; /* Strikethrough */
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
cfg = ulc ^ ibg; /* Underline */
|
||||
} else {
|
||||
for (uint8_t plane = 0; plane < 4; plane++, pmask = pmask << 1) {
|
||||
@@ -746,7 +746,7 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
}
|
||||
|
||||
static void
|
||||
text_line(incolor_t *dev, uint16_t ca)
|
||||
text_line(incolor_t *dev, uint16_t cursoraddr)
|
||||
{
|
||||
int drawcursor;
|
||||
uint8_t chr;
|
||||
@@ -755,12 +755,12 @@ text_line(incolor_t *dev, uint16_t ca)
|
||||
|
||||
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8) {
|
||||
chr = dev->vram[(dev->ma << 1) & 0x3fff];
|
||||
attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff];
|
||||
chr = dev->vram[(dev->memaddr << 1) & 0x3fff];
|
||||
attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
|
||||
drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron);
|
||||
|
||||
switch (dev->crtc[INCOLOR_CRTC_XMODE] & 5) {
|
||||
case 0:
|
||||
@@ -779,7 +779,7 @@ text_line(incolor_t *dev, uint16_t ca)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++dev->ma;
|
||||
++dev->memaddr;
|
||||
|
||||
if (drawcursor) {
|
||||
int cw = INCOLOR_CW;
|
||||
@@ -808,29 +808,29 @@ static void
|
||||
graphics_line(incolor_t *dev)
|
||||
{
|
||||
uint8_t mask;
|
||||
uint16_t ca;
|
||||
uint16_t cursoraddr;
|
||||
int plane;
|
||||
int col;
|
||||
uint8_t ink;
|
||||
uint16_t val[4];
|
||||
|
||||
/* Graphics mode. */
|
||||
ca = (dev->sc & 3) * 0x2000;
|
||||
cursoraddr = (dev->scanline & 3) * 0x2000;
|
||||
if ((dev->ctrl & INCOLOR_CTRL_PAGE1) && (dev->ctrl2 & INCOLOR_CTRL2_PAGE1))
|
||||
ca += 0x8000;
|
||||
cursoraddr += 0x8000;
|
||||
|
||||
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
|
||||
mask = dev->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */
|
||||
for (plane = 0; plane < 4; plane++, mask = mask >> 1) {
|
||||
if (dev->ctrl & 8) {
|
||||
if (mask & 1)
|
||||
val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1];
|
||||
val[plane] = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane] << 8) | dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane + 1];
|
||||
else
|
||||
val[plane] = 0;
|
||||
} else
|
||||
val[plane] = 0;
|
||||
}
|
||||
dev->ma++;
|
||||
dev->memaddr++;
|
||||
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
ink = 0;
|
||||
@@ -855,19 +855,19 @@ static void
|
||||
incolor_poll(void *priv)
|
||||
{
|
||||
incolor_t *dev = (incolor_t *) priv;
|
||||
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
int x;
|
||||
int oldvc;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int cw = INCOLOR_CW;
|
||||
|
||||
if (!dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
dev->status |= 1;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
scanline_old = dev->scanline;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = (dev->sc << 1) & 7;
|
||||
dev->scanline = (dev->scanline << 1) & 7;
|
||||
|
||||
if (dev->dispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
@@ -878,44 +878,43 @@ incolor_poll(void *priv)
|
||||
if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH))
|
||||
graphics_line(dev);
|
||||
else
|
||||
text_line(dev, ca);
|
||||
text_line(dev, cursoraddr);
|
||||
}
|
||||
dev->sc = oldsc;
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->stat |= 8;
|
||||
dev->scanline = scanline_old;
|
||||
if (dev->vc == dev->crtc[7] && !dev->scanline)
|
||||
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->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->cursorvisible = 0;
|
||||
}
|
||||
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->scanline = 0;
|
||||
}
|
||||
} else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
oldvc = dev->vc;
|
||||
} else if (dev->scanline == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) {
|
||||
dev->memaddr_backup = dev->memaddr;
|
||||
dev->scanline = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
if (dev->vc == dev->crtc[6])
|
||||
@@ -926,7 +925,7 @@ incolor_poll(void *priv)
|
||||
if (!dev->vadj)
|
||||
dev->dispon = 1;
|
||||
if (!dev->vadj)
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
if ((dev->crtc[10] & 0x60) == 0x20)
|
||||
dev->cursoron = 0;
|
||||
else
|
||||
@@ -972,13 +971,13 @@ incolor_poll(void *priv)
|
||||
dev->blink++;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
}
|
||||
|
||||
if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->con = 1;
|
||||
if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -75,9 +75,9 @@ typedef struct {
|
||||
int firstline, lastline;
|
||||
|
||||
int linepos, displine;
|
||||
int vc, sc;
|
||||
uint16_t ma, maback;
|
||||
int con, coff, cursoron;
|
||||
int vc, scanline;
|
||||
uint16_t memaddr, memaddr_backup;
|
||||
int cursorvisible, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
@@ -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:
|
||||
@@ -260,11 +260,11 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
else
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
|
||||
fnt = &(fontdatm[chr][dev->sc]);
|
||||
fnt = &(fontdatm[chr][dev->scanline]);
|
||||
|
||||
if (blk) {
|
||||
val = 0x000; /* Blinking, draw all background */
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
val = 0x1ff; /* Underscore, draw all foreground */
|
||||
} else {
|
||||
val = fnt[0] << 1;
|
||||
@@ -319,11 +319,11 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
else
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + dev->sc;
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + dev->scanline;
|
||||
|
||||
if (blk) {
|
||||
val = 0x000; /* Blinking, draw all background */
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
val = 0x1ff; /* Underscore, draw all foreground */
|
||||
} else {
|
||||
val = fnt[0] << 1;
|
||||
@@ -384,11 +384,11 @@ draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
else
|
||||
elg = ((chr >= 0xc0) && (chr <= 0xdf));
|
||||
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc;
|
||||
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->scanline;
|
||||
|
||||
if (blk) {
|
||||
val = 0x000; /* Blinking, draw all background */
|
||||
} else if (dev->sc == ull) {
|
||||
} else if (dev->scanline == ull) {
|
||||
val = 0x1ff; /* Underscore, draw all foreground */
|
||||
} else {
|
||||
val = fnt[0] << 1;
|
||||
@@ -404,7 +404,7 @@ draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
|
||||
}
|
||||
|
||||
static void
|
||||
text_line(herculesplus_t *dev, uint16_t ca)
|
||||
text_line(herculesplus_t *dev, uint16_t cursoraddr)
|
||||
{
|
||||
int drawcursor;
|
||||
uint8_t chr;
|
||||
@@ -413,12 +413,12 @@ text_line(herculesplus_t *dev, uint16_t ca)
|
||||
|
||||
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8) {
|
||||
chr = dev->vram[(dev->ma << 1) & 0x3fff];
|
||||
attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff];
|
||||
chr = dev->vram[(dev->memaddr << 1) & 0x3fff];
|
||||
attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
|
||||
drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron);
|
||||
|
||||
switch (dev->crtc[HERCULESPLUS_CRTC_XMODE] & 5) {
|
||||
case 0:
|
||||
@@ -437,7 +437,7 @@ text_line(herculesplus_t *dev, uint16_t ca)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++dev->ma;
|
||||
++dev->memaddr;
|
||||
|
||||
if (drawcursor) {
|
||||
int cw = HERCULESPLUS_CW;
|
||||
@@ -452,24 +452,24 @@ text_line(herculesplus_t *dev, uint16_t ca)
|
||||
static void
|
||||
graphics_line(herculesplus_t *dev)
|
||||
{
|
||||
uint16_t ca;
|
||||
uint16_t cursoraddr;
|
||||
int c;
|
||||
int plane = 0;
|
||||
uint16_t val;
|
||||
|
||||
/* Graphics mode. */
|
||||
ca = (dev->sc & 3) * 0x2000;
|
||||
cursoraddr = (dev->scanline & 3) * 0x2000;
|
||||
if ((dev->ctrl & HERCULESPLUS_CTRL_PAGE1) && (dev->ctrl2 & HERCULESPLUS_CTRL2_PAGE1))
|
||||
ca += 0x8000;
|
||||
cursoraddr += 0x8000;
|
||||
|
||||
for (uint8_t x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8)
|
||||
val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8)
|
||||
| dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1];
|
||||
val = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane] << 8)
|
||||
| dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane + 1];
|
||||
else
|
||||
val = 0;
|
||||
|
||||
dev->ma++;
|
||||
dev->memaddr++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[dev->displine][(x << 4) + c] = (val & 0x8000) ? 7 : 0;
|
||||
|
||||
@@ -485,20 +485,20 @@ static void
|
||||
herculesplus_poll(void *priv)
|
||||
{
|
||||
herculesplus_t *dev = (herculesplus_t *) priv;
|
||||
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
int x;
|
||||
int oldvc;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int cw = HERCULESPLUS_CW;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE();
|
||||
if (!dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
dev->status |= 1;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
scanline_old = dev->scanline;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = (dev->sc << 1) & 7;
|
||||
dev->scanline = (dev->scanline << 1) & 7;
|
||||
if (dev->dispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
dev->firstline = dev->displine;
|
||||
@@ -508,7 +508,7 @@ herculesplus_poll(void *priv)
|
||||
if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH))
|
||||
graphics_line(dev);
|
||||
else
|
||||
text_line(dev, ca);
|
||||
text_line(dev, cursoraddr);
|
||||
|
||||
if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH))
|
||||
x = dev->crtc[1] << 4;
|
||||
@@ -517,40 +517,39 @@ herculesplus_poll(void *priv)
|
||||
|
||||
video_process_8(x, dev->displine);
|
||||
}
|
||||
dev->sc = oldsc;
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->stat |= 8;
|
||||
dev->scanline = scanline_old;
|
||||
if (dev->vc == dev->crtc[7] && !dev->scanline)
|
||||
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->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->cursorvisible = 0;
|
||||
}
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->scanline = 0;
|
||||
}
|
||||
} else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
} else if (dev->scanline == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) {
|
||||
dev->memaddr_backup = dev->memaddr;
|
||||
dev->scanline = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
@@ -562,7 +561,7 @@ herculesplus_poll(void *priv)
|
||||
if (!dev->vadj)
|
||||
dev->dispon = 1;
|
||||
if (!dev->vadj)
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
if ((dev->crtc[10] & 0x60) == 0x20)
|
||||
dev->cursoron = 0;
|
||||
else
|
||||
@@ -607,13 +606,13 @@ herculesplus_poll(void *priv)
|
||||
dev->blink++;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->scanline++;
|
||||
dev->scanline &= 31;
|
||||
dev->memaddr = dev->memaddr_backup;
|
||||
}
|
||||
|
||||
if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->con = 1;
|
||||
if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1)))
|
||||
dev->cursorvisible = 1;
|
||||
}
|
||||
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
@@ -448,7 +448,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -660,10 +660,10 @@ ht216_recalctimings(svga_t *svga)
|
||||
break;
|
||||
}
|
||||
|
||||
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
|
||||
svga->memaddr_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
|
||||
|
||||
if (ht216->ht_regs[0xf6] & 0x80)
|
||||
svga->ma_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12);
|
||||
svga->memaddr_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12);
|
||||
|
||||
svga->interlace = ht216->ht_regs[0xe0] & 0x01;
|
||||
|
||||
|
||||
@@ -113,10 +113,10 @@ typedef struct jega_t {
|
||||
uint8_t attr_palette_enable;
|
||||
uint32_t *pallook;
|
||||
int is_vga;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int cursorblink_disable;
|
||||
int ca;
|
||||
int cursoraddr;
|
||||
int font_index;
|
||||
int sbcsbank_inv;
|
||||
int attr3_sbcsbank;
|
||||
@@ -222,14 +222,14 @@ jega_render_text(void *priv)
|
||||
&jega->ega.x_add;
|
||||
int * y_add = jega->is_vga ? &jega->vga.svga.y_add :
|
||||
&jega->ega.y_add;
|
||||
int * sc = jega->is_vga ? &jega->vga.svga.sc :
|
||||
&jega->ega.sc;
|
||||
int * sc = jega->is_vga ? &jega->vga.svga.scanline :
|
||||
&jega->ega.scanline;
|
||||
int * hdisp = jega->is_vga ? &jega->vga.svga.hdisp :
|
||||
&jega->ega.hdisp;
|
||||
int * scrollcache = jega->is_vga ? &jega->vga.svga.scrollcache :
|
||||
&jega->ega.scrollcache;
|
||||
uint32_t *ma = jega->is_vga ? &jega->vga.svga.ma :
|
||||
&jega->ega.ma;
|
||||
uint32_t *memaddr = jega->is_vga ? &jega->vga.svga.memaddr :
|
||||
&jega->ega.memaddr;
|
||||
uint8_t mask = jega->is_vga ? jega->vga.svga.dac_mask : 0xff;
|
||||
|
||||
if (*firstline_draw == 2000)
|
||||
@@ -260,12 +260,12 @@ jega_render_text(void *priv)
|
||||
|
||||
if (jega->is_vga) {
|
||||
if (!jega->vga.svga.force_old_addr)
|
||||
addr = jega->vga.svga.remap_func(&jega->vga.svga, jega->vga.svga.ma) &
|
||||
addr = jega->vga.svga.remap_func(&jega->vga.svga, jega->vga.svga.memaddr) &
|
||||
jega->vga.svga.vram_display_mask;
|
||||
} else
|
||||
addr = jega->ega.remap_func(&jega->ega, *ma) & jega->ega.vrammask;
|
||||
addr = jega->ega.remap_func(&jega->ega, *memaddr) & jega->ega.vrammask;
|
||||
|
||||
int drawcursor = ((*ma == jega->ca) && cursoron);
|
||||
int drawcursor = ((*memaddr == jega->cursoraddr) && cursoron);
|
||||
|
||||
uint32_t chr;
|
||||
uint32_t attr;
|
||||
@@ -399,9 +399,9 @@ jega_render_text(void *priv)
|
||||
p += charwidth;
|
||||
}
|
||||
}
|
||||
*ma += 4;
|
||||
*memaddr += 4;
|
||||
}
|
||||
*ma &= 0x3ffff;
|
||||
*memaddr &= 0x3ffff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ jega_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case RCCLH:
|
||||
case RCCLL:
|
||||
jega->ca = jega->regs[RCCLH] << 10 | jega->regs[RCCLL] << 2;
|
||||
jega->cursoraddr = jega->regs[RCCLH] << 10 | jega->regs[RCCLL] << 2;
|
||||
break;
|
||||
case RCMOD:
|
||||
jega->cursoron = (val & 0x80);
|
||||
|
||||
@@ -6,16 +6,19 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* MDA emulation.
|
||||
* IBM Monochrome Display and Printer Adapter emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Connor Hyde, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
* Copyright 2025 starfrost / Connor Hyde
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -33,7 +36,17 @@
|
||||
#include <86box/vid_mda.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
static int mdacols[256][2][2];
|
||||
// Enumerates MDA monitor types
|
||||
enum mda_monitor_type_e {
|
||||
MDA_MONITOR_TYPE_DEFAULT = 0, // Default MDA monitor type.
|
||||
MDA_MONITOR_TYPE_GREEN = 1, // Green phosphor
|
||||
MDA_MONITOR_TYPE_AMBER = 2, // Amber phosphor
|
||||
MDA_MONITOR_TYPE_GRAY = 3, // Gray phosphor
|
||||
MDA_MONITOR_TYPE_RGBI = 4, // RGBI colour monitor with modified rev1 or rev0 MDA card for colour support
|
||||
} mda_monitor_type;
|
||||
|
||||
// [attr][blink][fg]
|
||||
static int mda_attr_to_color_table[256][2][2];
|
||||
|
||||
static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
@@ -44,32 +57,31 @@ 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
|
||||
@@ -78,23 +90,23 @@ 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;
|
||||
|
||||
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 +130,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;
|
||||
@@ -130,59 +142,141 @@ mda_recalctimings(mda_t *mda)
|
||||
void
|
||||
mda_poll(void *priv)
|
||||
{
|
||||
mda_t *mda = (mda_t *) priv;
|
||||
uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int oldvc;
|
||||
mda_t *mda = (mda_t *) priv;
|
||||
uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
bool drawcursor;
|
||||
int32_t oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
int oldsc;
|
||||
int blink;
|
||||
int32_t scanline_old;
|
||||
int32_t blink;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
|
||||
if (!mda->linepos) {
|
||||
timer_advance_u64(&mda->timer, mda->dispofftime);
|
||||
mda->stat |= 1;
|
||||
mda->status |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
scanline_old = mda->scanline;
|
||||
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;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
mda->lastline = mda->displine;
|
||||
for (x = 0; x < mda->crtc[1]; x++) {
|
||||
chr = mda->vram[(mda->ma << 1) & 0xfff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
if (mda->sc == 12 && ((attr & 7) == 1)) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr + mda->fontbase][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if ((chr & ~0x1f) == 0xc0)
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr + mda->fontbase][mda->sc] & 1];
|
||||
else
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||
|
||||
for (uint32_t 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->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
// Colours that will be used
|
||||
int32_t color_bg = 0, color_fg = 0;
|
||||
|
||||
// If we are using an RGBI monitor allow colour
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
color_bg = (attr >> 4) & 0x0F;
|
||||
color_fg = (attr & 0x0F);
|
||||
|
||||
// turn off bright bg colours in blink mode
|
||||
if ((mda->mode & MDA_MODE_BLINK)
|
||||
&& (color_bg & 0x8))
|
||||
color_bg & ~(0x8);
|
||||
|
||||
// black-on-non black or white colours forced to white
|
||||
// grey-on-colours forced to bright white
|
||||
|
||||
bool special_treatment = (color_bg != 0 && color_bg != 7);
|
||||
|
||||
if (color_fg == MDA_COLOR_GREY
|
||||
&& special_treatment)
|
||||
color_fg = MDA_COLOR_BRIGHT_WHITE;
|
||||
|
||||
if (color_fg == 0
|
||||
&& special_treatment)
|
||||
color_fg = MDA_COLOR_GREY;
|
||||
|
||||
// gray is black
|
||||
if (color_fg == MDA_COLOR_GREY
|
||||
&& (color_bg == MDA_COLOR_GREY || color_bg == MDA_COLOR_BLACK))
|
||||
color_fg = MDA_COLOR_BLACK;
|
||||
}
|
||||
mda->ma++;
|
||||
|
||||
if (mda->scanline == 12
|
||||
&& ((attr & 7) == 1)) { // underline
|
||||
for (uint32_t column = 0; column < 9; column++) {
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
buffer32->line[mda->displine][(x * 9) + column] = CGAPAL_CGA_START + color_fg;
|
||||
} else
|
||||
buffer32->line[mda->displine][(x * 9) + column] = mda_attr_to_color_table[attr][blink][1];
|
||||
}
|
||||
} else { // character
|
||||
for (uint32_t column = 0; column < 8; column++) {
|
||||
// bg=0, fg=1
|
||||
bool is_fg = (fontdatm[chr + mda->fontbase][mda->scanline] & (1 << (column ^ 7))) ? 1 : 0;
|
||||
|
||||
uint32_t font_char = mda_attr_to_color_table[attr][blink][is_fg];
|
||||
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
if (!is_fg)
|
||||
font_char = CGAPAL_CGA_START + color_bg;
|
||||
else
|
||||
font_char = CGAPAL_CGA_START + color_fg;
|
||||
}
|
||||
|
||||
buffer32->line[mda->displine][(x * 9) + column] = font_char;
|
||||
}
|
||||
|
||||
// these characters (C0-DF) have their background extended to their 9th column
|
||||
if ((chr & ~0x1f) == 0xc0) {
|
||||
bool is_fg = fontdatm[chr + mda->fontbase][mda->scanline] & 1;
|
||||
uint32_t final_result = mda_attr_to_color_table[attr][blink][is_fg];
|
||||
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
if (!is_fg)
|
||||
final_result = CGAPAL_CGA_START + color_bg;
|
||||
else
|
||||
final_result = CGAPAL_CGA_START + color_fg;
|
||||
}
|
||||
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = final_result;
|
||||
|
||||
} else {
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = CGAPAL_CGA_START + color_bg;
|
||||
|
||||
} else
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = mda_attr_to_color_table[attr][blink][0];
|
||||
}
|
||||
}
|
||||
|
||||
mda->memaddr++;
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||
for (uint32_t column = 0; column < 9; column++) {
|
||||
if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI
|
||||
&& !(mda->mode & MDA_MODE_BW)) {
|
||||
buffer32->line[mda->displine][(x * 9) + column] ^= CGAPAL_CGA_START + color_fg;
|
||||
} else
|
||||
buffer32->line[mda->displine][(x * 9) + column] ^= mda_attr_to_color_table[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
video_process_8(mda->crtc[1] * 9, mda->displine);
|
||||
video_process_8(mda->crtc[MDA_CRTC_HDISP] * 9, mda->displine);
|
||||
}
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc) {
|
||||
mda->stat |= 8;
|
||||
mda->scanline = scanline_old;
|
||||
if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline) {
|
||||
mda->status |= 8;
|
||||
}
|
||||
mda->displine++;
|
||||
if (mda->displine >= 500)
|
||||
@@ -190,54 +284,60 @@ 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->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
|
||||
mda->con = 0;
|
||||
mda->coff = 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) {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr = mda->memaddr_backup;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj) {
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
mda->dispon = 1;
|
||||
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->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) {
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
oldvc = mda->vc;
|
||||
} 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->ma = mda->maback = (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]) {
|
||||
uint32_t x = mda->crtc[MDA_CRTC_HDISP] * 9;
|
||||
mda->lastline++;
|
||||
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) {
|
||||
xsize = x;
|
||||
@@ -253,8 +353,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;
|
||||
@@ -262,12 +362,15 @@ mda_poll(void *priv)
|
||||
mda->blink++;
|
||||
}
|
||||
} else {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr = mda->memaddr_backup;
|
||||
}
|
||||
if (mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))) {
|
||||
mda->con = 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;
|
||||
}
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
@@ -276,30 +379,32 @@ mda_poll(void *priv)
|
||||
void
|
||||
mda_init(mda_t *mda)
|
||||
{
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdacols[c][0][1] = 15 + 16;
|
||||
|
||||
for (uint16_t attr = 0; attr < 256; attr++) {
|
||||
mda_attr_to_color_table[attr][0][0] = mda_attr_to_color_table[attr][1][0] = mda_attr_to_color_table[attr][1][1] = 16;
|
||||
if (attr & 8)
|
||||
mda_attr_to_color_table[attr][0][1] = 15 + 16;
|
||||
else
|
||||
mdacols[c][0][1] = 7 + 16;
|
||||
mda_attr_to_color_table[attr][0][1] = 7 + 16;
|
||||
}
|
||||
mdacols[0x70][0][1] = 16;
|
||||
mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
|
||||
mdacols[0xF0][0][1] = 16;
|
||||
mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
|
||||
mdacols[0x78][0][1] = 16 + 7;
|
||||
mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
|
||||
mdacols[0xF8][0][1] = 16 + 7;
|
||||
mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
mda_attr_to_color_table[0x70][0][1] = 16;
|
||||
mda_attr_to_color_table[0x70][0][0] = mda_attr_to_color_table[0x70][1][0] = mda_attr_to_color_table[0x70][1][1] = CGAPAL_CGA_START + 15;
|
||||
mda_attr_to_color_table[0xF0][0][1] = 16;
|
||||
mda_attr_to_color_table[0xF0][0][0] = mda_attr_to_color_table[0xF0][1][0] = mda_attr_to_color_table[0xF0][1][1] = CGAPAL_CGA_START + 15;
|
||||
mda_attr_to_color_table[0x78][0][1] = CGAPAL_CGA_START + 7;
|
||||
mda_attr_to_color_table[0x78][0][0] = mda_attr_to_color_table[0x78][1][0] = mda_attr_to_color_table[0x78][1][1] = CGAPAL_CGA_START + 15;
|
||||
mda_attr_to_color_table[0xF8][0][1] = CGAPAL_CGA_START + 7;
|
||||
mda_attr_to_color_table[0xF8][0][0] = mda_attr_to_color_table[0xF8][1][0] = mda_attr_to_color_table[0xF8][1][1] = CGAPAL_CGA_START + 15;
|
||||
mda_attr_to_color_table[0x00][0][1] = mda_attr_to_color_table[0x00][1][1] = 16;
|
||||
mda_attr_to_color_table[0x08][0][1] = mda_attr_to_color_table[0x08][1][1] = 16;
|
||||
mda_attr_to_color_table[0x80][0][1] = mda_attr_to_color_table[0x80][1][1] = 16;
|
||||
mda_attr_to_color_table[0x88][0][1] = mda_attr_to_color_table[0x88][1][1] = 16;
|
||||
|
||||
overscan_x = overscan_y = 0;
|
||||
mda->monitor_index = monitor_index_global;
|
||||
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
mda->monitor_type = device_get_config_int("rgb_type");
|
||||
cga_palette = mda->monitor_type << 1;
|
||||
if (cga_palette > 6) {
|
||||
cga_palette = 0;
|
||||
}
|
||||
@@ -317,7 +422,7 @@ mda_standalone_init(UNUSED(const device_t *info))
|
||||
|
||||
mda->vram = malloc(0x1000);
|
||||
|
||||
switch(device_get_config_int("font")) {
|
||||
switch (device_get_config_int("font")) {
|
||||
case 0:
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
break;
|
||||
@@ -354,7 +459,7 @@ mda_standalone_init(UNUSED(const device_t *info))
|
||||
void
|
||||
mda_setcol(int chr, int blink, int fg, uint8_t cga_ink)
|
||||
{
|
||||
mdacols[chr][blink][fg] = 16 + cga_ink;
|
||||
mda_attr_to_color_table[chr][blink][fg] = CGAPAL_CGA_START + cga_ink;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -375,7 +480,7 @@ mda_speed_changed(void *priv)
|
||||
}
|
||||
|
||||
static const device_config_t mda_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "Display type",
|
||||
@@ -384,12 +489,14 @@ static const device_config_t mda_config[] = {
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Default", .value = 0 },
|
||||
{ .description = "Green", .value = 1 },
|
||||
{ .description = "Amber", .value = 2 },
|
||||
{ .description = "Gray", .value = 3 },
|
||||
{ .description = "" }
|
||||
.selection =
|
||||
{
|
||||
{ .description = "Default", .value = MDA_MONITOR_TYPE_DEFAULT },
|
||||
{ .description = "Green", .value = MDA_MONITOR_TYPE_GREEN },
|
||||
{ .description = "Amber", .value = MDA_MONITOR_TYPE_AMBER },
|
||||
{ .description = "Gray", .value = MDA_MONITOR_TYPE_GRAY },
|
||||
{ .description = "Generic RGBI color monitor", .value = MDA_MONITOR_TYPE_RGBI },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
@@ -401,17 +508,18 @@ static const device_config_t mda_config[] = {
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "US (CP 437)", .value = 0 },
|
||||
.selection =
|
||||
{
|
||||
{ .description = "US (CP 437)", .value = 0 },
|
||||
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
|
||||
{ .description = "" }
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t mda_device = {
|
||||
|
||||
@@ -736,7 +736,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) {
|
||||
if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -768,24 +768,24 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) |
|
||||
svga->memaddr_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) |
|
||||
(svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) {
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
}
|
||||
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
|
||||
if (svga->ma_latch != mystique->ma_latch_old) {
|
||||
if (svga->memaddr_latch != mystique->ma_latch_old) {
|
||||
if (svga->interlace && svga->oddeven)
|
||||
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2) + (svga->rowoffset << 1);
|
||||
svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) +
|
||||
(svga->memaddr_latch << 2) + (svga->rowoffset << 1);
|
||||
else
|
||||
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2);
|
||||
mystique->ma_latch_old = svga->ma_latch;
|
||||
svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) +
|
||||
(svga->memaddr_latch << 2);
|
||||
mystique->ma_latch_old = svga->memaddr_latch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,9 +895,9 @@ mystique_vblank_start(svga_t *svga)
|
||||
mystique_t *mystique = (mystique_t *) svga->priv;
|
||||
|
||||
if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) {
|
||||
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
svga->memaddr_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,29 +984,29 @@ mystique_recalctimings(svga_t *svga)
|
||||
svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS);
|
||||
|
||||
if (mystique->type >= MGA_1064SG)
|
||||
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
svga->memaddr_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
|
||||
if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) {
|
||||
svga->rowoffset <<= 1;
|
||||
if (mystique->type >= MGA_1064SG)
|
||||
svga->ma_latch <<= 1;
|
||||
svga->memaddr_latch <<= 1;
|
||||
}
|
||||
|
||||
if (mystique->type >= MGA_1064SG) {
|
||||
/*Mystique and later, unlike most SVGA cards, allows display start to take
|
||||
effect mid-screen*/
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->ma_latch <<= 1;
|
||||
/* Only change maback so the new display start will take effect on the next
|
||||
svga->memaddr_latch <<= 1;
|
||||
/* Only change memaddr_backup so the new display start will take effect on the next
|
||||
horizontal retrace. */
|
||||
if (svga->ma_latch != mystique->ma_latch_old) {
|
||||
if (svga->memaddr_latch != mystique->ma_latch_old) {
|
||||
if (svga->interlace && svga->oddeven)
|
||||
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2) + (svga->rowoffset << 1);
|
||||
svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) +
|
||||
(svga->memaddr_latch << 2) + (svga->rowoffset << 1);
|
||||
else
|
||||
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2);
|
||||
mystique->ma_latch_old = svga->ma_latch;
|
||||
svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) +
|
||||
(svga->memaddr_latch << 2);
|
||||
mystique->ma_latch_old = svga->memaddr_latch;
|
||||
}
|
||||
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
|
||||
@@ -124,7 +124,7 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if ((idx < 0x0e) || (idx > 0x10)) {
|
||||
if (idx == 0x0c || idx == 0x0d) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -393,9 +393,9 @@ oti_recalctimings(svga_t *svga)
|
||||
|
||||
if (oti->chip_id > 0) {
|
||||
if (oti->regs[0x14] & 0x08)
|
||||
svga->ma_latch |= 0x10000;
|
||||
svga->memaddr_latch |= 0x10000;
|
||||
if (oti->regs[0x16] & 0x08)
|
||||
svga->ma_latch |= 0x20000;
|
||||
svga->memaddr_latch |= 0x20000;
|
||||
|
||||
if (oti->regs[0x14] & 0x01)
|
||||
svga->vtotal += 0x400;
|
||||
|
||||
@@ -245,7 +245,7 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
|
||||
703
src/video/vid_pcjr.c
Normal file
703
src/video/vid_pcjr.c
Normal file
@@ -0,0 +1,703 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* IBM PCjr video subsystem emulation
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Connor Hyde / starfrost <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
#include <86box/m_pcjr.h>
|
||||
|
||||
static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/
|
||||
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void
|
||||
recalc_address(pcjr_t *pcjr)
|
||||
{
|
||||
uint8_t masked_memctrl = pcjr->memctrl;
|
||||
|
||||
/* According to the Technical Reference, bits 2 and 5 are
|
||||
ignored if there is only 64k of RAM and there are only
|
||||
4 pages. */
|
||||
if (mem_size < 128)
|
||||
masked_memctrl &= ~0x24;
|
||||
|
||||
if ((pcjr->memctrl & 0xc0) == 0xc0) {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x06) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11];
|
||||
} else {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x07) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcjr_recalc_timings(pcjr_t *pcjr)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
disptime = pcjr->crtc[0] + 1;
|
||||
_dispontime = pcjr->crtc[1];
|
||||
} else {
|
||||
disptime = (pcjr->crtc[0] + 1) << 1;
|
||||
_dispontime = pcjr->crtc[1] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
pcjr->dispontime = (uint64_t) (_dispontime);
|
||||
pcjr->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_size(pcjr_t *pcjr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
ret = 128;
|
||||
else
|
||||
ret = 256;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
pcjr->crtcreg = val & 0x1f;
|
||||
return;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
old = pcjr->crtc[pcjr->crtcreg];
|
||||
pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg];
|
||||
if (pcjr->crtcreg == 2)
|
||||
overscan_x = vid_get_h_overscan_size(pcjr);
|
||||
if (old != val) {
|
||||
if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) {
|
||||
pcjr->fullchange = changeframecount;
|
||||
pcjr_recalc_timings(pcjr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3da:
|
||||
if (!pcjr->array_ff)
|
||||
pcjr->array_index = val & 0x1f;
|
||||
else {
|
||||
if (pcjr->array_index & 0x10)
|
||||
val &= 0x0f;
|
||||
pcjr->array[pcjr->array_index & 0x1f] = val;
|
||||
if (!(pcjr->array_index & 0x1f))
|
||||
update_cga16_color(val);
|
||||
}
|
||||
pcjr->array_ff = !pcjr->array_ff;
|
||||
break;
|
||||
|
||||
case 0x3df:
|
||||
pcjr->memctrl = val;
|
||||
pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to
|
||||
then be readable from port 60, others it errors out
|
||||
with only 64k RAM set (but somehow, still works with
|
||||
128k or more RAM). */
|
||||
pcjr->addr_mode = val >> 6;
|
||||
recalc_address(pcjr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
ret = pcjr->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = pcjr->crtc[pcjr->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x3da:
|
||||
pcjr->array_ff = 0;
|
||||
pcjr->status ^= 0x10;
|
||||
ret = pcjr->status;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return;
|
||||
|
||||
pcjr->b8000[addr & 0x3fff] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_read(uint32_t addr, void *priv)
|
||||
{
|
||||
const pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return 0xff;
|
||||
|
||||
return (pcjr->b8000[addr & 0x3fff]);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_delta(pcjr_t *pcjr)
|
||||
{
|
||||
int def;
|
||||
int coef;
|
||||
int ret;
|
||||
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
def = 0x2c; /* I'm going to assume a datasheet erratum here. */
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
def = 0x5a;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
default:
|
||||
def = 0x2c;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = pcjr->crtc[0x02] - def;
|
||||
|
||||
if (ret < -8)
|
||||
ret = -8;
|
||||
|
||||
if (ret > 8)
|
||||
ret = 8;
|
||||
|
||||
return ret * coef;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_blit_h_overscan(pcjr_t *pcjr)
|
||||
{
|
||||
int cols = (pcjr->array[2] & 0xf) + 16;;
|
||||
int y0 = pcjr->firstline << 1;
|
||||
int y = (pcjr->lastline << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int i;
|
||||
int x;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
hline(buffer32, 0, y0 + i, x, cols);
|
||||
hline(buffer32, 0, y + i, x, cols);
|
||||
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y0 + i]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y + i]);
|
||||
} else {
|
||||
video_process_8(x, y0 + i);
|
||||
video_process_8(x, y + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_poll(void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint16_t cursoraddr = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int scanline_old;
|
||||
int l = (pcjr->displine << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int ho_d = vid_get_h_overscan_delta(pcjr) + (ho_s / 2);
|
||||
|
||||
if (!pcjr->linepos) {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispofftime);
|
||||
pcjr->status &= ~1;
|
||||
pcjr->linepos = 1;
|
||||
scanline_old = pcjr->scanline;
|
||||
if ((pcjr->crtc[8] & 3) == 3)
|
||||
pcjr->scanline = (pcjr->scanline << 1) & 7;
|
||||
if (pcjr->dispon) {
|
||||
uint16_t offset = 0;
|
||||
uint16_t mask = 0x1fff;
|
||||
|
||||
if (pcjr->displine < pcjr->firstline) {
|
||||
pcjr->firstline = pcjr->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
pcjr->lastline = pcjr->displine;
|
||||
cols[0] = (pcjr->array[2] & 0xf) + 16;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
|
||||
switch (pcjr->addr_mode) {
|
||||
case 0: /*Alpha*/
|
||||
offset = 0;
|
||||
mask = 0x3fff;
|
||||
break;
|
||||
case 1: /*Low resolution graphics*/
|
||||
offset = (pcjr->scanline & 1) * 0x2000;
|
||||
break;
|
||||
case 3: /*High resolution graphics*/
|
||||
offset = (pcjr->scanline & 3) * 0x2000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
pcjr->memaddr++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
pcjr->memaddr++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] =
|
||||
buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] =
|
||||
buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] =
|
||||
buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] =
|
||||
buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] =
|
||||
buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] =
|
||||
buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1] << 8) |
|
||||
pcjr->vram[((pcjr->memaddr << 1) & mask) + offset];
|
||||
pcjr->memaddr++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
chr = (dat >> 7) & 1;
|
||||
chr |= ((dat >> 14) & 2);
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->memaddr == cursoraddr) && pcjr->cursorvisible && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
if (pcjr->scanline & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] =
|
||||
cols[(fontdat[chr][pcjr->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
pcjr->memaddr++;
|
||||
}
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->memaddr == cursoraddr) && pcjr->cursorvisible && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
pcjr->memaddr++;
|
||||
if (pcjr->scanline & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] =
|
||||
cols[(fontdat[chr][pcjr->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
cols[2] = pcjr->array[2 + 16] + 16;
|
||||
cols[3] = pcjr->array[3 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
pcjr->memaddr++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1];
|
||||
pcjr->memaddr++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pcjr->array[3] & 4) {
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
}
|
||||
} else {
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l + 1]);
|
||||
} else {
|
||||
video_process_8(x, l);
|
||||
video_process_8(x, l + 1);
|
||||
}
|
||||
pcjr->scanline = scanline_old;
|
||||
if (pcjr->vc == pcjr->crtc[7] && !pcjr->scanline) {
|
||||
pcjr->status |= 8;
|
||||
}
|
||||
pcjr->displine++;
|
||||
if (pcjr->displine >= 360)
|
||||
pcjr->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispontime);
|
||||
if (pcjr->dispon)
|
||||
pcjr->status |= 1;
|
||||
pcjr->linepos = 0;
|
||||
if (pcjr->vsynctime) {
|
||||
pcjr->vsynctime--;
|
||||
if (!pcjr->vsynctime) {
|
||||
pcjr->status &= ~8;
|
||||
}
|
||||
}
|
||||
if (pcjr->scanline == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == ((pcjr->crtc[11] & 31) >> 1))) {
|
||||
pcjr->cursorvisible = 0;
|
||||
}
|
||||
if (pcjr->vadj) {
|
||||
pcjr->scanline++;
|
||||
pcjr->scanline &= 31;
|
||||
pcjr->memaddr = pcjr->memaddr_backup;
|
||||
pcjr->vadj--;
|
||||
if (!pcjr->vadj) {
|
||||
pcjr->dispon = 1;
|
||||
pcjr->memaddr = pcjr->memaddr_backup = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
pcjr->scanline = 0;
|
||||
}
|
||||
} else if (pcjr->scanline == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == (pcjr->crtc[9] >> 1))) {
|
||||
pcjr->memaddr_backup = pcjr->memaddr;
|
||||
pcjr->scanline = 0;
|
||||
oldvc = pcjr->vc;
|
||||
pcjr->vc++;
|
||||
pcjr->vc &= 127;
|
||||
if (pcjr->vc == pcjr->crtc[6])
|
||||
pcjr->dispon = 0;
|
||||
if (oldvc == pcjr->crtc[4]) {
|
||||
pcjr->vc = 0;
|
||||
pcjr->vadj = pcjr->crtc[5];
|
||||
if (!pcjr->vadj)
|
||||
pcjr->dispon = 1;
|
||||
if (!pcjr->vadj)
|
||||
pcjr->memaddr = pcjr->memaddr_backup = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
if ((pcjr->crtc[10] & 0x60) == 0x20)
|
||||
pcjr->cursoron = 0;
|
||||
else
|
||||
pcjr->cursoron = pcjr->blink & 16;
|
||||
}
|
||||
if (pcjr->vc == pcjr->crtc[7]) {
|
||||
pcjr->dispon = 0;
|
||||
pcjr->displine = 0;
|
||||
pcjr->vsynctime = 16;
|
||||
picint(1 << 5);
|
||||
if (pcjr->crtc[7]) {
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
pcjr->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (pcjr->lastline - pcjr->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
int actual_ys = ys_temp;
|
||||
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= ho_s;
|
||||
|
||||
if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
vid_blit_h_overscan(pcjr);
|
||||
|
||||
if (enable_overscan) {
|
||||
video_blit_memtoscreen(0, pcjr->firstline << 1,
|
||||
xsize, actual_ys + 32);
|
||||
} else if (pcjr->apply_hd) {
|
||||
video_blit_memtoscreen(ho_s / 2, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
} else {
|
||||
video_blit_memtoscreen(ho_d, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
}
|
||||
pcjr->firstline = 1000;
|
||||
pcjr->lastline = 0;
|
||||
pcjr->blink++;
|
||||
}
|
||||
} else {
|
||||
pcjr->scanline++;
|
||||
pcjr->scanline &= 31;
|
||||
pcjr->memaddr = pcjr->memaddr_backup;
|
||||
}
|
||||
if (pcjr->scanline == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == ((pcjr->crtc[10] & 31) >> 1)))
|
||||
pcjr->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pcjr_vid_init(pcjr_t *pcjr)
|
||||
{
|
||||
int display_type;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
|
||||
|
||||
pcjr->memctrl = -1;
|
||||
if (mem_size < 128)
|
||||
pcjr->memctrl &= ~0x24;
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
pcjr->composite = (display_type != PCJR_RGB);
|
||||
pcjr->apply_hd = device_get_config_int("apply_hd");
|
||||
overscan_x = 256;
|
||||
overscan_y = 32;
|
||||
|
||||
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
|
||||
vid_read, NULL, NULL,
|
||||
vid_write, NULL, NULL, NULL, 0, pcjr);
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr);
|
||||
timer_add(&pcjr->timer, vid_poll, pcjr, 1);
|
||||
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
}
|
||||
@@ -2342,23 +2342,23 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
int drawcursor = 0;
|
||||
uint32_t cols[2];
|
||||
int pitch = (dev->mapram[0x3e9] + 1) * 2;
|
||||
uint16_t sc = (dev->displine & 0x0f) % pitch;
|
||||
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff;
|
||||
uint16_t scanline = (dev->displine & 0x0f) % pitch;
|
||||
uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff;
|
||||
const uint8_t *addr;
|
||||
uint32_t val;
|
||||
int cw = (w == 80) ? 8 : 16;
|
||||
|
||||
addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe];
|
||||
ma += (dev->displine / pitch) * w;
|
||||
addr = &dev->cga_vram[((memaddr + ((dev->displine / pitch) * w)) * 2) & 0x3ffe];
|
||||
memaddr += (dev->displine / pitch) * w;
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
chr = *addr++;
|
||||
attr = *addr++;
|
||||
|
||||
/* Cursor enabled? */
|
||||
if (ma == ca && (dev->cgablink & 8) && (dev->mapram[0x3ea] & 0x60) != 0x20) {
|
||||
drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (sc >> 1)) && ((dev->mapram[0x3eb] & 0x1f) >= (sc >> 1));
|
||||
if (memaddr == cursoraddr && (dev->cgablink & 8) && (dev->mapram[0x3ea] & 0x60) != 0x20) {
|
||||
drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (scanline >> 1)) && ((dev->mapram[0x3eb] & 0x1f) >= (scanline >> 1));
|
||||
} else
|
||||
drawcursor = 0;
|
||||
|
||||
@@ -2374,9 +2374,9 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
|
||||
for (int c = 0; c < cw; c++) {
|
||||
if (drawcursor)
|
||||
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
val = cols[(fontdatm[chr + dev->fontbase][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
else
|
||||
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
val = cols[(fontdatm[chr + dev->fontbase][scanline] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (cw == 8) /* 80x25 CGA text screen. */
|
||||
buffer32->line[dev->displine][(x * cw) + c] = val;
|
||||
else { /* 40x25 CGA text screen. */
|
||||
@@ -2385,7 +2385,7 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
}
|
||||
}
|
||||
|
||||
ma++;
|
||||
memaddr++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2395,7 +2395,7 @@ pgc_cga_gfx40(pgc_t *dev)
|
||||
{
|
||||
uint32_t cols[4];
|
||||
int col;
|
||||
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
const uint8_t *addr;
|
||||
uint16_t dat;
|
||||
|
||||
@@ -2422,9 +2422,9 @@ pgc_cga_gfx40(pgc_t *dev)
|
||||
}
|
||||
|
||||
for (uint8_t x = 0; x < 40; x++) {
|
||||
addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
|
||||
addr = &dev->cga_vram[(memaddr + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
|
||||
dat = (addr[0] << 8) | addr[1];
|
||||
dev->ma++;
|
||||
dev->memaddr++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[dev->displine][(x << 4) + (c << 1)] = buffer32->line[dev->displine][(x << 4) + (c << 1) + 1] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
@@ -2437,7 +2437,7 @@ void
|
||||
pgc_cga_gfx80(pgc_t *dev)
|
||||
{
|
||||
uint32_t cols[2];
|
||||
uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff;
|
||||
const uint8_t *addr;
|
||||
uint16_t dat;
|
||||
|
||||
@@ -2445,9 +2445,9 @@ pgc_cga_gfx80(pgc_t *dev)
|
||||
cols[1] = (dev->mapram[0x3d9] & 15) + 16;
|
||||
|
||||
for (uint8_t x = 0; x < 40; x++) {
|
||||
addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
|
||||
addr = &dev->cga_vram[(memaddr + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
|
||||
dat = (addr[0] << 8) | addr[1];
|
||||
dev->ma++;
|
||||
dev->memaddr++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[dev->displine][(x << 4) + c] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
|
||||
@@ -349,7 +349,7 @@ typedef struct da2_t {
|
||||
int lowres;
|
||||
int rowcount;
|
||||
double clock;
|
||||
uint32_t ma_latch, ca_adj;
|
||||
uint32_t memaddr_latch, ca_adj;
|
||||
|
||||
uint64_t dispontime, dispofftime;
|
||||
pc_timer_t timer;
|
||||
@@ -358,11 +358,11 @@ typedef struct da2_t {
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
|
||||
uint32_t ma, maback, ca;
|
||||
uint32_t memaddr, memaddr_backup, cursoraddr;
|
||||
int vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int linepos, vslines, linecountff;
|
||||
int con, cursoron, blink, blinkconf;
|
||||
int cursorvisible, cursoron, blink, blinkconf;
|
||||
int scrollcache;
|
||||
int char_width;
|
||||
|
||||
@@ -1960,10 +1960,10 @@ da2_render_text(da2_t *da2)
|
||||
uint32_t chr_dbcs;
|
||||
int chr_wide = 0;
|
||||
int colormode = ((da2->attrc[LV_PAS_STATUS_CNTRL] & 0x80) == 0x80);
|
||||
// da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc);
|
||||
// da2_log("\nda2ma: %x, da2sc: %x\n", da2->memaddr, da2->scanline);
|
||||
for (x = 0; x < da2->hdisp; x += 13) {
|
||||
chr = da2->cram[(da2->ma) & DA2_MASK_CRAM];
|
||||
attr = da2->cram[(da2->ma + 1) & DA2_MASK_CRAM];
|
||||
chr = da2->cram[(da2->memaddr) & DA2_MASK_CRAM];
|
||||
attr = da2->cram[(da2->memaddr + 1) & DA2_MASK_CRAM];
|
||||
// if(chr!=0x20) da2_log("chr: %x, attr: %x ", chr, attr);
|
||||
if (colormode) /* IO 3E8h, Index 1Dh */
|
||||
{ /* --Parse attribute byte in color mode-- */
|
||||
@@ -2003,11 +2003,11 @@ da2_render_text(da2_t *da2)
|
||||
/* Stay drawing If the char code is DBCS and not at last column. */
|
||||
if (chr_wide) {
|
||||
/* Get high DBCS code from the next video address */
|
||||
chr_dbcs = da2->cram[(da2->ma + 2) & DA2_MASK_CRAM];
|
||||
chr_dbcs = da2->cram[(da2->memaddr + 2) & DA2_MASK_CRAM];
|
||||
chr_dbcs <<= 8;
|
||||
chr_dbcs |= chr;
|
||||
/* Get the font pattern */
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2);
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2);
|
||||
/* Draw 13 dots */
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x80000000) ? fg : bg]];
|
||||
@@ -2020,10 +2020,10 @@ da2_render_text(da2_t *da2)
|
||||
fontbase = DA2_GAIJIRAM_SBEX;
|
||||
else
|
||||
fontbase = DA2_GAIJIRAM_SBCS;
|
||||
uint16_t font = da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2]; /* w13xh29 font */
|
||||
uint16_t font = da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2]; /* w13xh29 font */
|
||||
font <<= 8;
|
||||
font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2 + 1]; /* w13xh29 font */
|
||||
// if(chr!=0x20) da2_log("ma: %x, sc: %x, chr: %x, font: %x ", da2->ma, da2->sc, chr, font);
|
||||
font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2 + 1]; /* w13xh29 font */
|
||||
// if(chr!=0x20) da2_log("memaddr: %x, scanline: %x, chr: %x, font: %x ", da2->memaddr, da2->scanline, chr, font);
|
||||
/* Draw 13 dots */
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]];
|
||||
@@ -2033,7 +2033,7 @@ da2_render_text(da2_t *da2)
|
||||
}
|
||||
/* right half of DBCS */
|
||||
else {
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2);
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2);
|
||||
/* Draw 13 dots */
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]];
|
||||
@@ -2042,7 +2042,7 @@ da2_render_text(da2_t *da2)
|
||||
chr_wide = 0;
|
||||
}
|
||||
/* Line 28 (Underscore) Note: Draw this first to display blink + vertical + underline correctly. */
|
||||
if (da2->sc == da2->crtc[LC_UNDERLINE_LOCATION] && attr & 0x40 && !colormode) { /* Underscore only in monochrome mode */
|
||||
if (da2->scanline == da2->crtc[LC_UNDERLINE_LOCATION] && attr & 0x40 && !colormode) { /* Underscore only in monochrome mode */
|
||||
for (uint32_t n = 0; n < 13; n++)
|
||||
p[n] = da2->pallook[da2->egapal[fg]]; /* under line (white) */
|
||||
}
|
||||
@@ -2050,13 +2050,13 @@ da2_render_text(da2_t *da2)
|
||||
if (attr & 0x10) {
|
||||
p[0] = da2->pallook[da2->egapal[(colormode) ? IRGBtoBGRI(da2->attrc[LV_GRID_COLOR_0]) : 2]]; /* vertical line (white) */
|
||||
}
|
||||
if (da2->sc == 0 && attr & 0x20 && ~da2->attrc[LV_PAS_STATUS_CNTRL]) { /* HGrid */
|
||||
if (da2->scanline == 0 && attr & 0x20 && ~da2->attrc[LV_PAS_STATUS_CNTRL]) { /* HGrid */
|
||||
for (uint32_t n = 0; n < 13; n++)
|
||||
p[n] = da2->pallook[da2->egapal[(colormode) ? IRGBtoBGRI(da2->attrc[LV_GRID_COLOR_0]) : 2]]; /* horizontal line (white) */
|
||||
}
|
||||
/* Drawing text cursor */
|
||||
drawcursor = ((da2->ma == da2->ca) && da2->con && da2->cursoron);
|
||||
if (drawcursor && da2->sc >= da2->crtc[LC_CURSOR_ROW_START] && da2->sc <= da2->crtc[LC_CURSOR_ROW_END]) {
|
||||
drawcursor = ((da2->memaddr == da2->cursoraddr) && da2->cursorvisible && da2->cursoron);
|
||||
if (drawcursor && da2->scanline >= da2->crtc[LC_CURSOR_ROW_START] && da2->scanline <= da2->crtc[LC_CURSOR_ROW_END]) {
|
||||
int cursorwidth = (da2->crtc[LC_COMPATIBILITY] & 0x20 ? 26 : 13);
|
||||
int cursorcolor = (colormode) ? IRGBtoBGRI(da2->attrc[LV_CURSOR_COLOR]) : 2; /* Choose color 2 if mode 8 */
|
||||
fg = (colormode) ? getPS55ForeColor(attr, da2) : ((attr & 0x08) ? 3 : 2);
|
||||
@@ -2071,10 +2071,10 @@ da2_render_text(da2_t *da2)
|
||||
else
|
||||
p[n] = (p[n] == da2->pallook[da2->egapal[bg]]) ? da2->pallook[da2->egapal[cursorcolor]] : p[n];
|
||||
}
|
||||
da2->ma += 2;
|
||||
da2->memaddr += 2;
|
||||
p += 13;
|
||||
}
|
||||
// da2->ma &= DA2_MASK_CRAM;
|
||||
// da2->memaddr &= DA2_MASK_CRAM;
|
||||
// da2->writelines++;
|
||||
}
|
||||
}
|
||||
@@ -2096,12 +2096,12 @@ da2_render_textm3(da2_t *da2)
|
||||
int fg, bg;
|
||||
uint32_t chr_dbcs;
|
||||
int chr_wide = 0;
|
||||
// da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc);
|
||||
// da2_log("\nda2ma: %x, da2sc: %x\n", da2->memaddr, da2->scanline);
|
||||
for (x = 0; x < da2->hdisp; x += 13) {
|
||||
chr = da2_vram_r(DA2_VM03_BASECHR + da2->ma, da2);
|
||||
attr = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 1, da2);
|
||||
extattr = da2_vram_r(DA2_VM03_BASEEXATTR + da2->ma + 1, da2);
|
||||
// if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->ma << 1) & da2->vram_mask, chr, attr);
|
||||
chr = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr, da2);
|
||||
attr = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr + 1, da2);
|
||||
extattr = da2_vram_r(DA2_VM03_BASEEXATTR + da2->memaddr + 1, da2);
|
||||
// if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->memaddr << 1) & da2->vram_mask, chr, attr);
|
||||
bg = attr >> 4;
|
||||
// if (da2->blink) bg &= ~0x8;
|
||||
// fg = (da2->blink || (!(attr & 0x80))) ? (attr & 0xf) : bg;
|
||||
@@ -2118,11 +2118,11 @@ da2_render_textm3(da2_t *da2)
|
||||
/* Stay drawing if the char code is DBCS and not at last column. */
|
||||
if (chr_wide) {
|
||||
/* Get high DBCS code from the next video address */
|
||||
chr_dbcs = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 2, da2);
|
||||
chr_dbcs = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr + 2, da2);
|
||||
chr_dbcs <<= 8;
|
||||
chr_dbcs |= chr;
|
||||
/* Get the font pattern */
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2);
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2);
|
||||
/* Draw 13 dots */
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x80000000) ? fg : bg]];
|
||||
@@ -2135,10 +2135,10 @@ da2_render_textm3(da2_t *da2)
|
||||
fontbase = DA2_GAIJIRAM_SBEX;
|
||||
else
|
||||
fontbase = DA2_GAIJIRAM_SBCS;
|
||||
uint16_t font = da2->mmio.ram[fontbase+ chr * 0x40 + da2->sc * 2]; /* w13xh29 font */
|
||||
uint16_t font = da2->mmio.ram[fontbase+ chr * 0x40 + da2->scanline * 2]; /* w13xh29 font */
|
||||
font <<= 8;
|
||||
font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2 + 1]; /* w13xh29 font */
|
||||
// if(chr!=0x20) da2_log("ma: %x, sc: %x, chr: %x, font: %x ", da2->ma, da2->sc, chr, font);
|
||||
font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2 + 1]; /* w13xh29 font */
|
||||
// if(chr!=0x20) da2_log("memaddr: %x, scanline: %x, chr: %x, font: %x ", da2->memaddr, da2->scanline, chr, font);
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]];
|
||||
font <<= 1;
|
||||
@@ -2147,7 +2147,7 @@ da2_render_textm3(da2_t *da2)
|
||||
}
|
||||
/* right half of DBCS */
|
||||
else {
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2);
|
||||
uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2);
|
||||
/* Draw 13 dots */
|
||||
for (uint32_t n = 0; n < 13; n++) {
|
||||
p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]];
|
||||
@@ -2155,8 +2155,8 @@ da2_render_textm3(da2_t *da2)
|
||||
}
|
||||
chr_wide = 0;
|
||||
}
|
||||
drawcursor = ((da2->ma == da2->ca) && da2->con && da2->cursoron);
|
||||
if (drawcursor && da2->sc >= da2->crtc[LC_CURSOR_ROW_START] && da2->sc <= da2->crtc[LC_CURSOR_ROW_END]) {
|
||||
drawcursor = ((da2->memaddr == da2->cursoraddr) && da2->cursorvisible && da2->cursoron);
|
||||
if (drawcursor && da2->scanline >= da2->crtc[LC_CURSOR_ROW_START] && da2->scanline <= da2->crtc[LC_CURSOR_ROW_END]) {
|
||||
// int cursorwidth = (da2->crtc[0x1f] & 0x20 ? 26 : 13);
|
||||
// int cursorcolor = (colormode) ? IRGBtoBGRI(da2->attrc[0x1a]) : 2;/* Choose color 2 if mode 8 */
|
||||
// fg = (colormode) ? getPS55ForeColor(attr, da2) : (attr & 0x08) ? 3 : 2;
|
||||
@@ -2168,10 +2168,10 @@ da2_render_textm3(da2_t *da2)
|
||||
for (uint32_t n = 0; n < 13; n++)
|
||||
p[n] = da2->pallook[da2->egapal[fg]];
|
||||
}
|
||||
da2->ma += 2;
|
||||
da2->memaddr += 2;
|
||||
p += 13;
|
||||
}
|
||||
// da2->ma &= DA2_MASK_CRAM;
|
||||
// da2->memaddr &= DA2_MASK_CRAM;
|
||||
// da2->writelines++;
|
||||
}
|
||||
}
|
||||
@@ -2179,8 +2179,8 @@ da2_render_textm3(da2_t *da2)
|
||||
static void
|
||||
da2_render_color_4bpp(da2_t *da2)
|
||||
{
|
||||
int changed_offset = da2->ma >> 9;
|
||||
// da2_log("ma %x cf %x\n", da2->ma, changed_offset);
|
||||
int changed_offset = da2->memaddr >> 9;
|
||||
// da2_log("memaddr %x cf %x\n", da2->memaddr, changed_offset);
|
||||
da2->plane_mask &= 0x0f; /*safety */
|
||||
|
||||
if (da2->changedvram[changed_offset] || da2->changedvram[changed_offset + 1] || da2->fullchange) {
|
||||
@@ -2191,7 +2191,7 @@ da2_render_color_4bpp(da2_t *da2)
|
||||
if (da2->firstline_draw == 2000)
|
||||
da2->firstline_draw = da2->displine;
|
||||
da2->lastline_draw = da2->displine;
|
||||
// da2_log("d %X\n", da2->ma);
|
||||
// da2_log("d %X\n", da2->memaddr);
|
||||
|
||||
for (x = 0; x <= da2->hdisp; x += 8) /* hdisp = 1024 */
|
||||
{
|
||||
@@ -2199,9 +2199,9 @@ da2_render_color_4bpp(da2_t *da2)
|
||||
uint8_t dat;
|
||||
|
||||
/* get 8 pixels from vram */
|
||||
da2->ma &= da2->vram_display_mask;
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->ma << 3]);
|
||||
da2->ma += 1;
|
||||
da2->memaddr &= da2->vram_display_mask;
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->memaddr << 3]);
|
||||
da2->memaddr += 1;
|
||||
|
||||
dat = ((edat[0] >> 7) & (1 << 0)) | ((edat[1] >> 6) & (1 << 1)) | ((edat[2] >> 5) & (1 << 2)) | ((edat[3] >> 4) & (1 << 3));
|
||||
p[0] = da2->pallook[da2->egapal[dat & da2->plane_mask]];
|
||||
@@ -2228,8 +2228,8 @@ da2_render_color_4bpp(da2_t *da2)
|
||||
static void
|
||||
da2_render_color_8bpp(da2_t *da2)
|
||||
{
|
||||
int changed_offset = da2->ma >> 9;
|
||||
// da2_log("ma %x cf %x\n", da2->ma, changed_offset);
|
||||
int changed_offset = da2->memaddr >> 9;
|
||||
// da2_log("memaddr %x cf %x\n", da2->memaddr, changed_offset);
|
||||
|
||||
if (da2->changedvram[changed_offset] || da2->changedvram[changed_offset + 1] || da2->fullchange) {
|
||||
int x;
|
||||
@@ -2239,7 +2239,7 @@ da2_render_color_8bpp(da2_t *da2)
|
||||
if (da2->firstline_draw == 2000)
|
||||
da2->firstline_draw = da2->displine;
|
||||
da2->lastline_draw = da2->displine;
|
||||
// da2_log("d %X\n", da2->ma);
|
||||
// da2_log("d %X\n", da2->memaddr);
|
||||
|
||||
for (x = 0; x <= da2->hdisp; x += 8) /* hdisp = 1024 */
|
||||
{
|
||||
@@ -2247,10 +2247,10 @@ da2_render_color_8bpp(da2_t *da2)
|
||||
uint8_t dat;
|
||||
|
||||
/* get 8 pixels from vram */
|
||||
da2->ma &= da2->vram_display_mask;
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->ma << 3]);
|
||||
*(uint32_t *) (&edat[4]) = *(uint32_t *) (&da2->vram[(da2->ma << 3) + 4]);
|
||||
da2->ma += 1;
|
||||
da2->memaddr &= da2->vram_display_mask;
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->memaddr << 3]);
|
||||
*(uint32_t *) (&edat[4]) = *(uint32_t *) (&da2->vram[(da2->memaddr << 3) + 4]);
|
||||
da2->memaddr += 1;
|
||||
|
||||
dat = ((edat[0] >> 7) & (1 << 0)) | ((edat[1] >> 6) & (1 << 1)) | ((edat[2] >> 5) & (1 << 2)) | ((edat[3] >> 4) & (1 << 3)) | ((edat[4] >> 3) & (1 << 4)) | ((edat[5] >> 2) & (1 << 5)) | ((edat[6] >> 1) & (1 << 6)) | ((edat[7] >> 0) & (1 << 7));
|
||||
p[0] = da2->pallook[dat];
|
||||
@@ -2343,9 +2343,9 @@ da2_recalctimings(da2_t *da2)
|
||||
if (da2->rowoffset == 0)
|
||||
da2->rowoffset = 64 * 2; /* To avoid causing a DBZ error */
|
||||
if (da2->split == 0) /* To avoid a glitch in MODE 1 of OS/2 J1.3 DOSBox. */
|
||||
da2->ma_latch = 0;
|
||||
da2->memaddr_latch = 0;
|
||||
else
|
||||
da2->ma_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW];
|
||||
da2->memaddr_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW];
|
||||
|
||||
da2->ca_adj = 0;
|
||||
da2->rowcount = da2->crtc[LC_MAXIMUM_SCAN_LINE];
|
||||
@@ -3022,7 +3022,7 @@ da2_poll(void *priv)
|
||||
if (da2->dispon) {
|
||||
da2->hdisp_on = 1;
|
||||
|
||||
da2->ma &= da2->vram_display_mask;
|
||||
da2->memaddr &= da2->vram_display_mask;
|
||||
if (da2->firstline == 2000) {
|
||||
da2->firstline = da2->displine;
|
||||
video_wait_for_buffer();
|
||||
@@ -3035,7 +3035,7 @@ da2_poll(void *priv)
|
||||
da2->lastline = da2->displine;
|
||||
}
|
||||
|
||||
// da2_log("%03i %06X %06X\n", da2->displine, da2->ma,da2->vram_display_mask);
|
||||
// da2_log("%03i %06X %06X\n", da2->displine, da2->memaddr,da2->vram_display_mask);
|
||||
da2->displine++;
|
||||
if ((da2->cgastat & 8) && ((da2->displine & 0xf) == (da2->crtc[LC_VERTICAL_SYNC_END] & 0xf)) && da2->vslines) {
|
||||
// da2_log("Vsync off at line %i\n",displine);
|
||||
@@ -3045,9 +3045,9 @@ da2_poll(void *priv)
|
||||
if (da2->displine > 1200)
|
||||
da2->displine = 0;
|
||||
// da2_log("Col is %08X %08X %08X %i %i %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322],
|
||||
// displine, vc, ma);
|
||||
// displine, vc, memaddr);
|
||||
} else {
|
||||
// da2_log("VC %i ma %05X\n", da2->vc, da2->ma);
|
||||
// da2_log("VC %i memaddr %05X\n", da2->vc, da2->memaddr);
|
||||
timer_advance_u64(&da2->timer, da2->dispontime);
|
||||
|
||||
if (da2->dispon)
|
||||
@@ -3055,20 +3055,20 @@ da2_poll(void *priv)
|
||||
da2->hdisp_on = 0;
|
||||
|
||||
da2->linepos = 0;
|
||||
if (da2->sc == (da2->crtc[LC_CURSOR_ROW_END] & 31))
|
||||
da2->con = 0;
|
||||
if (da2->scanline == (da2->crtc[LC_CURSOR_ROW_END] & 31))
|
||||
da2->cursorvisible = 0;
|
||||
if (da2->dispon) {
|
||||
if (da2->sc == da2->rowcount) {
|
||||
if (da2->scanline == da2->rowcount) {
|
||||
da2->linecountff = 0;
|
||||
da2->sc = 0;
|
||||
da2->scanline = 0;
|
||||
|
||||
da2->maback += (da2->rowoffset << 1); /* color = 0x50(80), mono = 0x40(64) */
|
||||
da2->maback &= da2->vram_display_mask;
|
||||
da2->ma = da2->maback;
|
||||
da2->memaddr_backup += (da2->rowoffset << 1); /* color = 0x50(80), mono = 0x40(64) */
|
||||
da2->memaddr_backup &= da2->vram_display_mask;
|
||||
da2->memaddr = da2->memaddr_backup;
|
||||
} else {
|
||||
da2->sc++;
|
||||
da2->sc &= 31;
|
||||
da2->ma = da2->maback;
|
||||
da2->scanline++;
|
||||
da2->scanline &= 31;
|
||||
da2->memaddr = da2->memaddr_backup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3076,9 +3076,9 @@ da2_poll(void *priv)
|
||||
da2->vc &= 2047;
|
||||
|
||||
if (da2->vc == da2->split) {
|
||||
// da2->ma = da2->maback = da2->hblank_sub;
|
||||
da2->ma = da2->maback = 0;
|
||||
da2->sc = 0;
|
||||
// da2->memaddr = da2->memaddr_backup = da2->hblank_sub;
|
||||
da2->memaddr = da2->memaddr_backup = 0;
|
||||
da2->scanline = 0;
|
||||
// da2->displine = 0;
|
||||
}
|
||||
|
||||
@@ -3128,24 +3128,24 @@ da2_poll(void *priv)
|
||||
changeframecount = 2;
|
||||
da2->vslines = 0;
|
||||
|
||||
da2->ma
|
||||
= da2->maback = da2->ma_latch << 1;
|
||||
da2->ca = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj;
|
||||
da2->ca <<= 1;
|
||||
da2->memaddr
|
||||
= da2->memaddr_backup = da2->memaddr_latch << 1;
|
||||
da2->cursoraddr = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj;
|
||||
da2->cursoraddr <<= 1;
|
||||
|
||||
// da2_log("Addr %08X vson %03X vsoff %01X\n",da2->ma,da2->vsyncstart,da2->crtc[0x11]&0xF);
|
||||
// da2_log("Addr %08X vson %03X vsoff %01X\n",da2->memaddr,da2->vsyncstart,da2->crtc[0x11]&0xF);
|
||||
}
|
||||
if (da2->vc == da2->vtotal) {
|
||||
// da2_log("VC vtotal\n");
|
||||
// printf("Frame over at line %i %i %i %i\n",displine,vc,da2_vsyncstart,da2_dispend);
|
||||
da2->vc = 0;
|
||||
da2->sc = da2->crtc[LC_PRESET_ROW_SCANJ] & 0x1f;
|
||||
da2->scanline = da2->crtc[LC_PRESET_ROW_SCANJ] & 0x1f;
|
||||
da2->dispon = 1;
|
||||
da2->displine = 0;
|
||||
da2->scrollcache = da2->attrc[LV_PANNING] & 7;
|
||||
}
|
||||
if (da2->sc == (da2->crtc[LC_CURSOR_ROW_START] & 31))
|
||||
da2->con = 1;
|
||||
if (da2->scanline == (da2->crtc[LC_CURSOR_ROW_START] & 31))
|
||||
da2->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3231,7 +3231,7 @@ da2_reset(void *priv)
|
||||
da2->attrc[LV_CURSOR_COLOR] = 0x0f; /* cursor color */
|
||||
da2->crtc[LC_HORIZONTAL_TOTAL] = 63; /* Horizontal Total */
|
||||
da2->crtc[LC_VERTICAL_TOTALJ] = 255; /* Vertical Total (These two must be set before the timer starts.) */
|
||||
da2->ma_latch = 0;
|
||||
da2->memaddr_latch = 0;
|
||||
da2->attrc[LV_CURSOR_CONTROL] = 0x13; /* cursor options */
|
||||
da2->attr_palette_enable = 0; /* disable attribute generator */
|
||||
|
||||
@@ -3441,7 +3441,7 @@ static const device_config_t da2_configuration[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "charset",
|
||||
.description = "Charset",
|
||||
.description = "Character set",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = DA2_DCONFIG_CHARSET_JPAN,
|
||||
.selection = {
|
||||
|
||||
@@ -180,7 +180,7 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -211,7 +211,7 @@ rtg_recalctimings(svga_t *svga)
|
||||
{
|
||||
const rtg_t *dev = (rtg_t *) svga->priv;
|
||||
|
||||
svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17);
|
||||
svga->memaddr_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17);
|
||||
|
||||
svga->interlace = (svga->crtc[0x19] & 1);
|
||||
|
||||
|
||||
@@ -3179,9 +3179,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
if ((((svga->crtc[0x67] & 0xc) != 0xc) && (s3->chip >= S3_TRIO64V)) || (s3->chip < S3_TRIO64V))
|
||||
svga->ma_latch |= (s3->ma_ext << 16);
|
||||
svga->memaddr_latch |= (s3->ma_ext << 16);
|
||||
} else {
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -3503,7 +3503,7 @@ s3_recalctimings(svga_t *svga)
|
||||
}
|
||||
|
||||
svga->hdisp = svga->hdisp_old;
|
||||
svga->ma_latch |= (s3->ma_ext << 16);
|
||||
svga->memaddr_latch |= (s3->ma_ext << 16);
|
||||
|
||||
svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10));
|
||||
|
||||
@@ -4379,7 +4379,7 @@ s3_trio64v_recalctimings(svga_t *svga)
|
||||
|
||||
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
|
||||
{
|
||||
svga->ma_latch |= (s3->ma_ext << 16);
|
||||
svga->memaddr_latch |= (s3->ma_ext << 16);
|
||||
if (svga->crtc[0x51] & 0x30)
|
||||
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
|
||||
else if (svga->crtc[0x43] & 0x04)
|
||||
@@ -4427,9 +4427,9 @@ s3_trio64v_recalctimings(svga_t *svga)
|
||||
} else /*Streams mode*/
|
||||
{
|
||||
if (s3->streams.buffer_ctrl & 1)
|
||||
svga->ma_latch = s3->streams.pri_fb1 >> 2;
|
||||
svga->memaddr_latch = s3->streams.pri_fb1 >> 2;
|
||||
else
|
||||
svga->ma_latch = s3->streams.pri_fb0 >> 2;
|
||||
svga->memaddr_latch = s3->streams.pri_fb0 >> 2;
|
||||
|
||||
svga->hdisp = s3->streams.pri_w + 1;
|
||||
if (s3->streams.pri_h < svga->dispend)
|
||||
|
||||
@@ -688,10 +688,10 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) +
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) +
|
||||
((svga->crtc[8] & 0x60) >> 5);
|
||||
if ((svga->crtc[0x67] & 0xc) != 0xc)
|
||||
svga->ma_latch |= (virge->ma_ext << 16);
|
||||
svga->memaddr_latch |= (virge->ma_ext << 16);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
@@ -890,7 +890,7 @@ s3_virge_recalctimings(svga_t *svga)
|
||||
}
|
||||
|
||||
if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/
|
||||
svga->ma_latch |= (virge->ma_ext << 16);
|
||||
svga->memaddr_latch |= (virge->ma_ext << 16);
|
||||
if (svga->crtc[0x51] & 0x30)
|
||||
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
|
||||
else if (svga->crtc[0x43] & 0x04)
|
||||
@@ -935,9 +935,9 @@ s3_virge_recalctimings(svga_t *svga)
|
||||
} else { /*Streams mode*/
|
||||
if (virge->chip < S3_VIRGEGX2) {
|
||||
if (virge->streams.buffer_ctrl & 1)
|
||||
svga->ma_latch = virge->streams.pri_fb1 >> 2;
|
||||
svga->memaddr_latch = virge->streams.pri_fb1 >> 2;
|
||||
else
|
||||
svga->ma_latch = virge->streams.pri_fb0 >> 2;
|
||||
svga->memaddr_latch = virge->streams.pri_fb0 >> 2;
|
||||
|
||||
svga->hdisp = virge->streams.pri_w + 1;
|
||||
if (virge->streams.pri_h < svga->dispend)
|
||||
@@ -946,7 +946,7 @@ s3_virge_recalctimings(svga_t *svga)
|
||||
svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x;
|
||||
svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y;
|
||||
} else {
|
||||
svga->ma_latch |= (virge->ma_ext << 16);
|
||||
svga->memaddr_latch |= (virge->ma_ext << 16);
|
||||
if (svga->crtc[0x51] & 0x30)
|
||||
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
|
||||
else if (svga->crtc[0x43] & 0x04)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user