diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 5461cb71a..66783022e 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -6,13 +6,15 @@ * * This file is part of the 86Box distribution. * - * Implementation of the ACC 2168 chipset + * Implementation of the ACC 2046/2168 chipset * * * * Authors: Sarah Walker, + * Tiseno100 * * Copyright 2019 Sarah Walker. + * Copyright 2021 Tiseno100. */ #include #include @@ -28,84 +30,152 @@ #include <86box/port_92.h> #include <86box/chipset.h> -#define enabled_shadow (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) -#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY) +#define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) +#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) +#define SHADOW_ADDR ((i <= 1) ? (0xc0000 + (i << 15)) : (0xd0000 + ((i - 2) << 16))) +#define SHADOW_SIZE ((i <= 1) ? 0x8000 : 0x10000) +#define SHADOW_RECALC ((dev->regs[0x02] & (1 << i)) ? ENABLED_SHADOW : DISABLED_SHADOW) typedef struct acc2168_t { - int reg_idx; - uint8_t regs[256]; + uint8_t reg_idx, regs[256]; } acc2168_t; -static void +static void acc2168_shadow_recalc(acc2168_t *dev) { -mem_set_mem_state_both(0xc0000, 0x8000, ((dev->regs[0x02] & 0x01) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xc8000, 0x8000, ((dev->regs[0x02] & 0x02) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xd0000, 0x10000, ((dev->regs[0x02] & 0x04) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0x02] & 0x08) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0x02] & 0x10) ? enabled_shadow : disabled_shadow)); + for (uint32_t i = 0; i < 5; i++) + mem_set_mem_state_both(SHADOW_ADDR, SHADOW_SIZE, SHADOW_RECALC); } -static void +static void acc2168_write(uint16_t addr, uint8_t val, void *p) { acc2168_t *dev = (acc2168_t *)p; - if (!(addr & 1)) - dev->reg_idx = val; - else { - dev->regs[dev->reg_idx] = val; + switch (addr) + { + case 0xf2: + dev->reg_idx = val; + break; + case 0xf3: + pclog("dev->regs[%02x] = %02x\n", dev->reg_idx, val); + switch (dev->reg_idx) + { + case 0x00: + dev->regs[dev->reg_idx] = val; + break; - switch (dev->reg_idx) { - case 0x02: - acc2168_shadow_recalc(dev); - break; - } + case 0x01: + dev->regs[dev->reg_idx] = val & 0xd3; + cpu_update_waitstates(); + break; + + case 0x02: + dev->regs[dev->reg_idx] = val & 0x7f; + acc2168_shadow_recalc(dev); + break; + + case 0x03: + dev->regs[dev->reg_idx] = val & 0x1f; + break; + + case 0x04: + dev->regs[dev->reg_idx] = val; + cpu_cache_ext_enabled = !!(val & 0x01); + cpu_update_waitstates(); + break; + + case 0x05: + dev->regs[dev->reg_idx] = val & 0xf3; + break; + + case 0x06: + case 0x07: + dev->regs[dev->reg_idx] = val & 0x1f; + break; + + case 0x08: + dev->regs[dev->reg_idx] = val & 0x0f; + break; + + case 0x09: + dev->regs[dev->reg_idx] = val & 0x03; + break; + + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + dev->regs[dev->reg_idx] = val; + break; + + case 0x12: + dev->regs[dev->reg_idx] = val & 0xbb; + break; + + case 0x18: + dev->regs[dev->reg_idx] = val & 0x77; + break; + + case 0x19: + dev->regs[dev->reg_idx] = val & 0xfb; + break; + + case 0x1a: + dev->regs[dev->reg_idx] = val; + cpu_cache_int_enabled = !(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x1b: + dev->regs[dev->reg_idx] = val & 0xef; + break; + } + break; } } - -static uint8_t +static uint8_t acc2168_read(uint16_t addr, void *p) { acc2168_t *dev = (acc2168_t *)p; - if (!(addr & 1)) - return dev->reg_idx; - - return dev->regs[dev->reg_idx]; + return (addr == 0xf3) ? dev->regs[dev->reg_idx] : dev->reg_idx; } static void acc2168_close(void *priv) { - acc2168_t *dev = (acc2168_t *) priv; + acc2168_t *dev = (acc2168_t *)priv; free(dev); } - static void * acc2168_init(const device_t *info) { acc2168_t *dev = (acc2168_t *)malloc(sizeof(acc2168_t)); memset(dev, 0, sizeof(acc2168_t)); - - io_sethandler(0x00f2, 0x0002, - acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev); - device_add(&port_92_inv_device); + device_add(&port_92_device); + io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev); return dev; } - const device_t acc2168_device = { - "ACC 2168", + "ACC 2046/2168", 0, 0, - acc2168_init, acc2168_close, NULL, - { NULL }, NULL, NULL, - NULL -}; + acc2168_init, + acc2168_close, + NULL, + {NULL}, + NULL, + NULL, + NULL};