Re-organisation of video emulation.

This commit is contained in:
TomW 2013-06-24 20:42:35 +01:00
commit 58085bcc87
86 changed files with 8087 additions and 7229 deletions

View file

@ -1,99 +1,145 @@
/*PC1640 video emulation.
Mostly standard EGA, but with CGA & Hercules emulation*/
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
#include "io.h"
#include "mem.h"
#include "timer.h"
#include "video.h"
#include "vid_cga.h"
#include "vid_ega.h"
#include "vid_pc1640.h"
static int pc1640_cga=1;
void pc1640_out(uint16_t addr, uint8_t val, void *priv)
typedef struct pc1640_t
{
cga_t cga;
ega_t ega;
int cga_enabled;
int dispontime, dispofftime, vidtime;
} pc1640_t;
void pc1640_out(uint16_t addr, uint8_t val, void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
switch (addr)
{
case 0x3DB:
pc1640_cga=val&0x40;
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
if (pc1640_cga)
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
case 0x3db:
pc1640->cga_enabled = val & 0x40;
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
if (pc1640->cga_enabled)
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
else
{
switch (gdcreg[6] & 0xC)
switch (pc1640->ega.gdcreg[6] & 0xc)
{
case 0x0: /*128k at A0000*/
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
break;
case 0x4: /*64k at A0000*/
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
break;
case 0x8: /*32k at B0000*/
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
break;
case 0xC: /*32k at B8000*/
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
break;
}
}
pclog("3DB write %02X\n", val);
return;
}
if (pc1640_cga) cga_out(addr, val, NULL);
else ega_out(addr, val, NULL);
if (pc1640->cga_enabled) cga_out(addr, val, &pc1640->cga);
else ega_out(addr, val, &pc1640->ega);
}
uint8_t pc1640_in(uint16_t addr, void *priv)
uint8_t pc1640_in(uint16_t addr, void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
switch (addr)
{
}
if (pc1640_cga) return cga_in(addr, NULL);
else return ega_in(addr, NULL);
}
void pc1640_recalctimings()
{
if (pc1640_cga) cga_recalctimings();
else ega_recalctimings();
}
void pc1640_poll()
{
if (pc1640_cga) cga_poll();
else ega_poll();
}
int pc1640_init()
{
int r = ega_init();
pc1640_cga = 1;
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
return r;
if (pc1640->cga_enabled) return cga_in(addr, &pc1640->cga);
else return ega_in(addr, &pc1640->ega);
}
GFXCARD vid_pc1640 =
void pc1640_recalctimings(pc1640_t *pc1640)
{
if (pc1640->cga_enabled)
{
cga_recalctimings(&pc1640->cga);
pc1640->dispontime = pc1640->cga.dispontime;
pc1640->dispofftime = pc1640->cga.dispofftime;
}
else
{
ega_recalctimings(&pc1640->ega);
pc1640->dispontime = pc1640->ega.dispontime;
pc1640->dispofftime = pc1640->ega.dispofftime;
}
}
void pc1640_poll(void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
if (pc1640->cga_enabled)
{
pc1640->cga.vidtime = pc1640->vidtime;
cga_poll(&pc1640->cga);
pc1640->vidtime = pc1640->cga.vidtime;
}
else
{
pc1640->ega.vidtime = pc1640->vidtime;
ega_poll(&pc1640->ega);
pc1640->vidtime = pc1640->ega.vidtime;
}
}
void *pc1640_init()
{
pc1640_t *pc1640 = malloc(sizeof(pc1640_t));
cga_t *cga = &pc1640->cga;
ega_t *ega = &pc1640->ega;
memset(pc1640, 0, sizeof(pc1640_t));
ega_init(&pc1640->ega);
pc1640->cga.vram = pc1640->ega.vram;
pc1640->cga_enabled = 1;
cga_init(&pc1640->cga);
timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga);
io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);
return cga;
}
void pc1640_close(void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
free(pc1640->ega.vram);
free(pc1640);
}
void pc1640_speed_changed(void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
pc1640_recalctimings(pc1640);
}
device_t pc1640_device =
{
"Amstrad PC1640 (video)",
pc1640_init,
/*IO at 3Cx/3Dx*/
pc1640_out,
pc1640_in,
/*IO at 3Ax/3Bx*/
video_out_null,
video_in_null,
pc1640_poll,
pc1640_recalctimings,
ega_write,
video_write_null,
video_write_null,
ega_read,
video_read_null,
video_read_null
pc1640_close,
pc1640_speed_changed,
NULL
};