Slight GC100 rework.

This commit is contained in:
OBattler
2021-06-07 00:18:33 +02:00
parent 51b88518b8
commit cc310d663f

View File

@@ -7,15 +7,14 @@
* This file is part of the 86Box distribution. * This file is part of the 86Box distribution.
* *
* Implementation of the G2 GC100/GC100A chipset. * Implementation of the G2 GC100/GC100A chipset.
* NOTE: As documentation is currently available only for the * NOTE: As documentation is currently available only for the
* CG100 chipset, the GC100A chipset has been reverese-engineered. * CG100 chipset, the GC100A chipset has been reverese-engineered.
* Thus, its behavior may not be fully accurate. * Thus, its behavior may not be fully accurate.
* *
* Authors: EngiNerd <webmaster.crrc@yahoo.it> * Authors: EngiNerd, <webmaster.crrc@yahoo.it>
* *
* Copyright 2020-2021 EngiNerd * Copyright 2020-2021 EngiNerd.
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -42,15 +41,16 @@
#include <86box/io.h> #include <86box/io.h>
#include <86box/video.h> #include <86box/video.h>
typedef struct typedef struct
{ {
uint8_t reg[0x10]; uint8_t reg[0x10];
} gc100_t; } gc100_t;
#define ENABLE_GC100_LOG 1
#ifdef ENABLE_GC100_LOG #ifdef ENABLE_GC100_LOG
int gc100_do_log = ENABLE_GC100_LOG; int gc100_do_log = ENABLE_GC100_LOG;
static void static void
gc100_log(const char *fmt, ...) gc100_log(const char *fmt, ...)
{ {
@@ -66,136 +66,130 @@ gc100_log(const char *fmt, ...)
#define gc100_log(fmt, ...) #define gc100_log(fmt, ...)
#endif #endif
static uint8_t static uint8_t
get_fdd_switch_settings(){ get_fdd_switch_settings(void)
{
int i, fdd_count = 0; int i, fdd_count = 0;
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
if (fdd_get_flags(i)) if (fdd_get_flags(i))
fdd_count++; fdd_count++;
} }
if (!fdd_count) if (!fdd_count)
return 0x00; return 0x00;
else else
return ((fdd_count - 1) << 6) | 0x01; return ((fdd_count - 1) << 6) | 0x01;
} }
static uint8_t static uint8_t
get_videomode_switch_settings(){ get_videomode_switch_settings(void)
{
if (video_is_mda()) if (video_is_mda())
return 0x30; return 0x30;
else if (video_is_cga()) else if (video_is_cga())
return 0x20; /* 0x10 would be 40x25 */ return 0x20; /* 0x10 would be 40x25 */
else else
return 0x00; return 0x00;
} }
static void static void
gc100_write(uint16_t port, uint8_t val, void *priv) gc100_write(uint16_t port, uint8_t val, void *priv)
{ {
gc100_t *dev = (gc100_t *) priv; gc100_t *dev = (gc100_t *) priv;
uint16_t addr = port & 0xf; uint16_t addr = port & 0xf;
dev->reg[addr] = val; dev->reg[addr] = val;
switch (addr) switch (addr) {
{ /* addr 0x2
/* addr 0x2 * bits 5-7: not used
* bits 5-7: not used * bit 4: intenal memory wait states
* bit 4: intenal memory wait states * bits 2-3: external memory wait states
* bits 2-3: external memory wait states * bits 0-1: i/o access wait states
* bits 0-1: i/o access wait states */
*/ case 2:
case 0x2: break;
break;
/* addr 0x3
/* addr 0x3 * bits 1-7: not used
* bits 1-7: not used * bit 0: turbo 0 xt 1
* bit 0: turbo 0 xt 1 */
*/ case 3:
case 0x3: if (val & 1)
if (val & 0x1) cpu_dynamic_switch(0);
cpu_dynamic_switch(0); else
else cpu_dynamic_switch(cpu);
cpu_dynamic_switch(cpu); break;
break;
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
/* addr 0x6 */
/* addr 0x7 */
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
/* addr 0x6 */
/* addr 0x7 */
} }
gc100_log("GC100: Write %02x at %02x\n", val, port); gc100_log("GC100: Write %02x at %02x\n", val, port);
} }
static uint8_t static uint8_t
gc100_read(uint16_t port, void *priv) gc100_read(uint16_t port, void *priv)
{ {
gc100_t *dev = (gc100_t *) priv; gc100_t *dev = (gc100_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
uint16_t addr = port & 0xf; uint16_t addr = port & 0xf;
ret = dev->reg[addr]; ret = dev->reg[addr];
gc100_log("GC100: Read %02x at %02x\n", ret, port); gc100_log("GC100: Read %02x at %02x\n", ret, port);
switch (addr) switch (addr) {
{ /* addr 0x2
/* addr 0x2 * bits 5-7: not used
* bits 5-7: not used * bit 4: intenal memory wait states
* bit 4: intenal memory wait states * bits 2-3: external memory wait states
* bits 2-3: external memory wait states * bits 0-1: i/o access wait states
* bits 0-1: i/o access wait states */
*/ case 0x2:
case 0x2: break;
break;
/* addr 0x3
* bits 1-7: not used
* bit 0: turbo 0 xt 1
*/
case 0x3:
break;
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
case 0x5:
ret = ret & 0x0c;
ret |= get_fdd_switch_settings();
ret |= get_videomode_switch_settings();
if (hasfpu)
ret |= 0x02;
break; /* addr 0x3
* bits 1-7: not used
/* addr 0x6 */ * bit 0: turbo 0 xt 1
*/
/* addr 0x7 */ case 0x3:
break;
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
case 0x5:
ret = ret & 0x0c;
ret |= get_fdd_switch_settings();
ret |= get_videomode_switch_settings();
if (hasfpu)
ret |= 0x02;
break;
/* addr 0x6 */
/* addr 0x7 */
} }
return ret; return ret;
@@ -210,6 +204,7 @@ gc100_close(void *priv)
free(dev); free(dev);
} }
static void * static void *
gc100_init(const device_t *info) gc100_init(const device_t *info)
{ {
@@ -222,13 +217,12 @@ gc100_init(const device_t *info)
dev->reg[0x6] = 0x0; dev->reg[0x6] = 0x0;
dev->reg[0x7] = 0x0; dev->reg[0x7] = 0x0;
/* GC100A */ if (info->local) {
if(info->local) { /* GC100A */
io_sethandler(0x0c2, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); io_sethandler(0x0c2, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
io_sethandler(0x0c5, 0x03, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); io_sethandler(0x0c5, 0x03, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
} } else {
/* GC100 */ /* GC100 */
else {
io_sethandler(0x022, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); io_sethandler(0x022, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
io_sethandler(0x025, 0x01, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); io_sethandler(0x025, 0x01, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
} }
@@ -236,6 +230,7 @@ gc100_init(const device_t *info)
return dev; return dev;
} }
const device_t gc100_device = { const device_t gc100_device = {
"G2 GC100", "G2 GC100",
0, 0,
@@ -253,4 +248,3 @@ const device_t gc100a_device = {
{ NULL }, NULL, NULL, { NULL }, NULL, NULL,
NULL NULL
}; };