diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index d7ced9cc0..4fdbfc513 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -8,7 +8,7 @@ * * CPU type handler. * - * Version: @(#)cpu.h 1.0.6 2018/02/01 + * Version: @(#)cpu.h 1.0.7 2018/02/18 * * Authors: Sarah Walker, * leilei, @@ -70,7 +70,7 @@ typedef struct { - char name[32]; + const char *name; int cpu_type; int speed; int rspeed; diff --git a/src/device.c b/src/device.c index 0573eedf8..c258369b4 100644 --- a/src/device.c +++ b/src/device.c @@ -9,13 +9,13 @@ * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.c 1.0.7 2017/11/04 + * Version: @(#)device.c 1.0.8 2018/02/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2016 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -207,7 +207,7 @@ device_get_config_string(char *s) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_string(device_current->name, s, c->default_string)); + return(config_get_string((char *) device_current->name, s, (char *) c->default_string)); c++; } @@ -223,7 +223,7 @@ device_get_config_int(char *s) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_int(device_current->name, s, c->default_int)); + return(config_get_int((char *) device_current->name, s, c->default_int)); c++; } @@ -239,7 +239,7 @@ device_get_config_int_ex(char *s, int default_int) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_int(device_current->name, s, default_int)); + return(config_get_int((char *) device_current->name, s, default_int)); c++; } @@ -255,7 +255,7 @@ device_get_config_hex16(char *s) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_hex16(device_current->name, s, c->default_int)); + return(config_get_hex16((char *) device_current->name, s, c->default_int)); c++; } @@ -271,7 +271,7 @@ device_get_config_hex20(char *s) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_hex20(device_current->name, s, c->default_int)); + return(config_get_hex20((char *) device_current->name, s, c->default_int)); c++; } @@ -287,7 +287,7 @@ device_get_config_mac(char *s, int default_int) while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_mac(device_current->name, s, default_int)); + return(config_get_mac((char *) device_current->name, s, default_int)); c++; } @@ -303,7 +303,7 @@ device_set_config_int(char *s, int val) while (c && c->type != -1) { if (! strcmp(s, c->name)) { - config_set_int(device_current->name, s, val); + config_set_int((char *) device_current->name, s, val); break; } @@ -319,7 +319,7 @@ device_set_config_hex16(char *s, int val) while (c && c->type != -1) { if (! strcmp(s, c->name)) { - config_set_hex16(device_current->name, s, val); + config_set_hex16((char *) device_current->name, s, val); break; } @@ -335,7 +335,7 @@ device_set_config_hex20(char *s, int val) while (c && c->type != -1) { if (! strcmp(s, c->name)) { - config_set_hex20(device_current->name, s, val); + config_set_hex20((char *) device_current->name, s, val); break; } @@ -351,7 +351,7 @@ device_set_config_mac(char *s, int val) while (c && c->type != -1) { if (! strcmp(s, c->name)) { - config_set_mac(device_current->name, s, val); + config_set_mac((char *) device_current->name, s, val); break; } @@ -419,7 +419,7 @@ machine_get_config_int(char *s) c = d->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_int(d->name, s, c->default_int)); + return(config_get_int((char *) d->name, s, c->default_int)); c++; } @@ -439,7 +439,7 @@ machine_get_config_string(char *s) c = d->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_string(d->name, s, c->default_string)); + return(config_get_string((char *) d->name, s, (char *) c->default_string)); c++; } diff --git a/src/device.h b/src/device.h index 1174d08d9..5c55c7992 100644 --- a/src/device.h +++ b/src/device.h @@ -9,15 +9,15 @@ * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.h 1.0.7 2017/11/25 + * Version: @(#)device.h 1.0.8 2018/02/18 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2016 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef EMU_DEVICE_H # define EMU_DEVICE_H @@ -50,13 +50,13 @@ enum { typedef struct { - char description[256]; + const char *description; int value; } device_config_selection_t; typedef struct { - char description[256]; - char extensions[25][25]; + const char *description; + const char *extensions[5]; } device_config_file_filter_t; typedef struct { @@ -66,10 +66,10 @@ typedef struct { } device_config_spinner_t; typedef struct { - char name[256]; - char description[256]; + const char *name; + const char *description; int type; - char default_string[256]; + const char *default_string; int default_int; device_config_selection_t selection[16]; device_config_file_filter_t file_filter[16]; @@ -77,7 +77,7 @@ typedef struct { } device_config_t; typedef struct _device_ { - char name[50]; + const char *name; uint32_t flags; /* system flags */ uint32_t local; /* flags local to device */ diff --git a/src/dma.c b/src/dma.c index ff454ec5b..e5ebd8bff 100644 --- a/src/dma.c +++ b/src/dma.c @@ -774,11 +774,10 @@ void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t Total #if 0 mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); memcpy(&ram[PhysAddress], DataWrite, TotalSize); - #else for (i = 0; i < TotalSize; i++) mem_writeb_phys_dma(PhysAddress + i, DataWrite[i]); -#endif mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); +#endif } diff --git a/src/lpt.c b/src/lpt.c index 6d21440a3..56ec62299 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -17,8 +17,8 @@ char lpt_device_names[3][16]; static struct { - char name[64]; - char internal_name[16]; + const char *name; + const char *internal_name; lpt_device_t *device; } lpt_devices[] = { @@ -31,15 +31,15 @@ static struct char *lpt_device_get_name(int id) { - if (strlen(lpt_devices[id].name) == 0) + if (strlen((char *) lpt_devices[id].name) == 0) return NULL; - return lpt_devices[id].name; + return (char *) lpt_devices[id].name; } char *lpt_device_get_internal_name(int id) { - if (strlen(lpt_devices[id].internal_name) == 0) + if (strlen((char *) lpt_devices[id].internal_name) == 0) return NULL; - return lpt_devices[id].internal_name; + return (char *) lpt_devices[id].internal_name; } static lpt_device_t *lpt_device_ts[3]; @@ -53,10 +53,10 @@ void lpt_devices_init() for (i = 0; i < 3; i++) { c = 0; - while (strcmp(lpt_devices[c].internal_name, lpt_device_names[i]) && strlen(lpt_devices[c].internal_name) != 0) + while (strcmp((char *) lpt_devices[c].internal_name, lpt_device_names[i]) && strlen((char *) lpt_devices[c].internal_name) != 0) c++; - if (strlen(lpt_devices[c].internal_name) == 0) + if (strlen((char *) lpt_devices[c].internal_name) == 0) lpt_device_ts[i] = NULL; else { diff --git a/src/mem.c b/src/mem.c index 18a0d6700..3be2cd717 100644 --- a/src/mem.c +++ b/src/mem.c @@ -884,7 +884,7 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) uint8_t mem_readb_phys(uint32_t addr) { mem_logical_addr = 0xffffffff; - + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); @@ -894,16 +894,14 @@ uint8_t mem_readb_phys(uint32_t addr) /* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */ uint8_t mem_readb_phys_dma(uint32_t addr) { - mem_logical_addr = 0xffffffff; - - if (_mem_read_b[addr >> 14]) { - if (_mem_mapping_r[addr >> 14] && (_mem_mapping_r[addr >> 14]->flags & MEM_MAPPING_INTERNAL)) { - return _mem_exec[addr >> 14][addr & 0x3fff]; - } else - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - } - - return 0xff; + /* mem_logical_addr = 0xffffffff; */ + + if (_mem_exec[addr >> 14]) + return _mem_exec[addr >> 14][addr & 0x3fff]; + else if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + else + return 0xff; } uint16_t mem_readw_phys(uint32_t addr) @@ -919,7 +917,7 @@ uint16_t mem_readw_phys(uint32_t addr) void mem_writeb_phys(uint32_t addr, uint8_t val) { mem_logical_addr = 0xffffffff; - + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); } @@ -927,14 +925,12 @@ void mem_writeb_phys(uint32_t addr, uint8_t val) /* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */ void mem_writeb_phys_dma(uint32_t addr, uint8_t val) { - mem_logical_addr = 0xffffffff; - - if (_mem_write_b[addr >> 14]) { - if (_mem_mapping_w[addr >> 14] && (_mem_mapping_w[addr >> 14]->flags & MEM_MAPPING_INTERNAL)) { - _mem_exec[addr >> 14][addr & 0x3fff] = val; - } else - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - } + /* mem_logical_addr = 0xffffffff; */ + + if (_mem_exec[addr >> 14]) + _mem_exec[addr >> 14][addr & 0x3fff] = val; + else if (_mem_write_b[addr >> 14]) + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); } void mem_writew_phys(uint32_t addr, uint16_t val) diff --git a/src/network/network.c b/src/network/network.c index ec6e2755f..1c079247b 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.20 2018/01/26 + * Version: @(#)network.c 1.0.21 2018/02/18 * * Author: Fred N. van Kempen, * @@ -287,7 +287,7 @@ network_dev_to_id(char *devname) int i = 0; for (i=0; i */ @@ -36,8 +36,8 @@ typedef void (*NETRXCB)(void *, uint8_t *, int); typedef struct { - char name[64]; - char internal_name[32]; + const char *name; + const char *internal_name; device_t *device; void *priv; int (*poll)(void *); diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 9094a037e..e46c7b140 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -8,7 +8,7 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.14 2018/01/21 + * Version: @(#)scsi.c 1.0.15 2018/02/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -57,8 +57,8 @@ mutex_t *scsiMutex; typedef struct { - char name[64]; - char internal_name[32]; + const char *name; + const char *internal_name; device_t *device; void (*reset)(void *p); } SCSI_CARD; @@ -98,7 +98,7 @@ int scsi_card_available(int card) char *scsi_card_getname(int card) { - return(scsi_cards[card].name); + return((char *) scsi_cards[card].name); } @@ -118,7 +118,7 @@ int scsi_card_has_config(int card) char *scsi_card_get_internal_name(int card) { - return(scsi_cards[card].internal_name); + return((char *) scsi_cards[card].internal_name); } @@ -126,8 +126,8 @@ int scsi_card_get_from_internal_name(char *s) { int c = 0; - while (strlen(scsi_cards[c].internal_name)) { - if (!strcmp(scsi_cards[c].internal_name, s)) + while (strlen((char *) scsi_cards[c].internal_name)) { + if (!strcmp((char *) scsi_cards[c].internal_name, s)) return(c); c++; } diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 10dcb5f37..1d090d0cd 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -10,12 +10,12 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.36 2017/12/09 + * Version: @(#)scsi_aha154x.c 1.0.37 2018/02/17 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. * - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -36,6 +36,7 @@ #include "../timer.h" #include "../device.h" #include "../plat.h" +#include "../cpu/cpu.h" #include "scsi.h" #include "scsi_aha154x.h" #include "scsi_x54x.h" @@ -91,6 +92,7 @@ aha_log(const char *fmt, ...) va_list ap; if (aha_do_log) { + pclog("In %s mode: ",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); @@ -782,7 +784,7 @@ aha_init(device_t *info) switch(dev->Base) { case 0x0330: dev->bios_path = - L"roms/scsi/adaptec/aha1540b320_330.bin"; + L"roms/scsi/adaptec/aha1540b310.bin"; break; case 0x0334: @@ -790,9 +792,12 @@ aha_init(device_t *info) L"roms/scsi/adaptec/aha1540b320_334.bin"; break; } - dev->fw_rev = "A001"; + dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); + dev->int_geom_writable = 2; + dev->rom_shram = 0x3F80; /* shadow RAM address base */ + dev->rom_shramsz = 128; /* size of shadow RAM */ break; case AHA_154xC: diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index e249f41f3..b2a199f0c 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.11 2018/01/21 + * Version: @(#)scsi_device.c 1.0.12 2018/02/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -284,20 +284,6 @@ int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) } -int scsi_device_block_shift(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_CDROM: - return 11; /* 2048 bytes per block */ - default: - return 9; /* 512 bytes per block */ - } -} - - void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) { uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; diff --git a/src/scsi/scsi_device.h b/src/scsi/scsi_device.h index fd5f21c14..f89fac3bd 100644 --- a/src/scsi/scsi_device.h +++ b/src/scsi/scsi_device.h @@ -8,7 +8,7 @@ * * Definitions for the generic SCSI device command handler. * - * Version: @(#)scsi_device.h 1.0.4 2017/10/10 + * Version: @(#)scsi_device.h 1.0.5 2018/02/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -44,7 +44,6 @@ extern int scsi_device_read_capacity(uint8_t id, uint8_t lun, extern int scsi_device_present(uint8_t id, uint8_t lun); extern int scsi_device_valid(uint8_t id, uint8_t lun); extern int scsi_device_cdb_length(uint8_t id, uint8_t lun); -extern int scsi_device_block_shift(uint8_t id, uint8_t lun); extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len, uint8_t *cdb); extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index b531d3100..19e92c3b2 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.12 2018/02/15 + * Version: @(#)scsi_x54x.c 1.0.13 2018/02/17 * * Authors: TheCollector1995, * Miran Grca, @@ -39,6 +39,7 @@ #include "../device.h" #include "../timer.h" #include "../plat.h" +#include "../cpu/cpu.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_aha154x.h" @@ -81,6 +82,7 @@ x54x_log(const char *fmt, ...) va_list ap; if (x54x_do_log) { + pclog("In %s mode: ",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); @@ -303,7 +305,6 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) uint32_t dma_address; uint32_t lba; int sector_len = cmd->secount; - int block_shift; uint8_t ret; if (islba) @@ -345,8 +346,6 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) dev->CmdBuffer = NULL; } - block_shift = scsi_device_block_shift(cmd->id, cmd->lun); - switch(cmd->command) { case 0x00: /* Reset Disk System, in practice it's a nop */ return(0); @@ -380,9 +379,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) case 0x02: /* Read Desired Sectors to Memory */ target_check(cmd->id, cmd->lun); - dev->BufferLength = sector_len << block_shift; - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - memset(dev->CmdBuffer, 0x00, dev->BufferLength); + dev->BufferLength = -1; cdb[0] = GPCMD_READ_10; cdb[1] = (cmd->lun & 7) << 5; @@ -390,8 +387,8 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) cdb[3] = (lba >> 16) & 0xff; cdb[4] = (lba >> 8) & 0xff; cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; + cdb[7] = 0; + cdb[8] = sector_len; #if 0 x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount); #endif @@ -401,6 +398,8 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) if (dev->Phase == SCSI_PHASE_STATUS) goto skip_read_phase1; + dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); + scsi_device_command_phase1(cmd->id, cmd->lun); if (sector_len > 0) { x54x_log("BIOS DMA: Reading %i bytes at %08X\n", @@ -420,9 +419,7 @@ skip_read_phase1: case 0x03: /* Write Desired Sectors from Memory */ target_check(cmd->id, cmd->lun); - dev->BufferLength = sector_len << block_shift; - dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - memset(dev->CmdBuffer, 0x00, dev->BufferLength); + dev->BufferLength = -1; cdb[0] = GPCMD_WRITE_10; cdb[1] = (cmd->lun & 7) << 5; @@ -430,8 +427,8 @@ skip_read_phase1: cdb[3] = (lba >> 16) & 0xff; cdb[4] = (lba >> 8) & 0xff; cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; + cdb[7] = 0; + cdb[8] = sector_len; #if 0 x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount); #endif @@ -441,6 +438,8 @@ skip_read_phase1: if (dev->Phase == SCSI_PHASE_STATUS) goto skip_write_phase1; + dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); + if (sector_len > 0) { x54x_log("BIOS DMA: Reading %i bytes at %08X\n", dev->BufferLength, dma_address); @@ -467,8 +466,8 @@ skip_write_phase1: cdb[3] = (lba >> 16) & 0xff; cdb[4] = (lba >> 8) & 0xff; cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; + cdb[7] = 0; + cdb[8] = sector_len; scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); @@ -503,7 +502,7 @@ skip_write_phase1: x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, - dev->CmdBuffer, dev->BufferLength); + dev->CmdBuffer, 4 /* dev->BufferLength */); if (dev->CmdBuffer != NULL) { free(dev->CmdBuffer); @@ -569,7 +568,7 @@ skip_write_phase1: x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, - dev->CmdBuffer, dev->BufferLength); + dev->CmdBuffer, 4 /* dev->BufferLength */); if (dev->CmdBuffer != NULL) { free(dev->CmdBuffer); @@ -1290,6 +1289,7 @@ x54x_cmd_thread(void *priv) if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) { /* If we did not get anything, wait a while. */ thread_wait_event((event_t *) wait_evt, 10); + thread_reset_event((event_t *) wait_evt); scsi_mutex_wait(0); continue; @@ -1443,11 +1443,10 @@ static void x54x_reset(x54x_t *dev) { clear_irq(dev); - if (dev->int_geom_writable) + if (dev->int_geom_writable == 1) dev->Geometry = 0x80; else dev->Geometry = 0x00; - dev->Geometry = 0x00; dev->Command = 0xFF; dev->CmdParam = 0; dev->CmdParamLeft = 0; @@ -1800,7 +1799,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv) break; case 3: - if (dev->int_geom_writable) + if (dev->int_geom_writable == 1) dev->Geometry = val; break; } @@ -1964,6 +1963,7 @@ x54x_init(device_t *info) x54x_thread_start(dev); thread_wait_event((event_t *) thread_started, -1); + thread_reset_event((event_t *) thread_started); return(dev); } diff --git a/src/sound/sound.c b/src/sound/sound.c index 96de19948..de3bc47fd 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.c 1.0.13 2018/02/15 + * Version: @(#)sound.c 1.0.14 2018/02/18 * * Authors: Sarah Walker, * Miran Grca, @@ -43,8 +43,8 @@ typedef struct { - char name[64]; - char internal_name[24]; + const char *name; + const char *internal_name; device_t *device; } SOUND_CARD; @@ -112,7 +112,7 @@ int sound_card_available(int card) char *sound_card_getname(int card) { - return sound_cards[card].name; + return (char *) sound_cards[card].name; } device_t *sound_card_getdevice(int card) @@ -129,16 +129,16 @@ int sound_card_has_config(int card) char *sound_card_get_internal_name(int card) { - return sound_cards[card].internal_name; + return (char *) sound_cards[card].internal_name; } int sound_card_get_from_internal_name(char *s) { int c = 0; - while (strlen(sound_cards[c].internal_name)) + while (strlen((char *) sound_cards[c].internal_name)) { - if (!strcmp(sound_cards[c].internal_name, s)) + if (!strcmp((char *) sound_cards[c].internal_name, s)) return c; c++; } diff --git a/src/video/vid_cl5428.c b/src/video/vid_cl5428.c deleted file mode 100644 index 31272b806..000000000 --- a/src/video/vid_cl5428.c +++ /dev/null @@ -1,1028 +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 select Cirrus Logic cards (currently only GD5428 is fully supported). - * - * Version: @(#)vid_cl_5428.c 1.0.0 2018/12/11 - * - * Authors: Sarah Walker, - * Barry Rodewald, - * TheCollector1995, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2018 Barry Rodewald - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl5428.h" - -#define BIOS_GD5428_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB (Cirrus Logic 5428)_v3.04.bin" - -#define CIRRUS_ID_CLGD5422 0x8c -#define CIRRUS_ID_CLGD5428 0x98 -#define CIRRUS_ID_CLGD5429 0x9c -#define CIRRUS_ID_CLGD5430 0xa0 -#define CIRRUS_ID_CLGD5434 0xa8 -#define CIRRUS_ID_CLGD5436 0xac -#define CIRRUS_ID_CLGD5446 0xb8 - -/* sequencer 0x07 */ -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 - -/* sequencer 0x12 */ -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ - -/* control 0x30 */ -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - - -typedef struct gd5428_t -{ - mem_mapping_t mmio_mapping; - - svga_t svga; - - rom_t bios_rom; - - uint32_t vram_size; - uint8_t vram_code; - - uint8_t vclk_n[4]; - uint8_t vclk_d[4]; - uint32_t bank[2]; - - struct { - uint8_t state; - int ctrl; - PALETTE pal; - } ramdac; - - struct { - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint32_t dst_addr, src_addr; - uint8_t mask, mode, rop; - uint8_t status; - uint16_t trans_col, trans_mask; - - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - - int sys_tx; - uint8_t sys_cnt; - uint32_t sys_buf; - uint16_t pixel_cnt; - uint16_t scan_cnt; - } blt; -} gd5428_t; - - -static void -gd5428_blit_dword(gd5428_t *gd5428, svga_t *svga); - -static void -gd5428_blit_byte(gd5428_t *gd5428, svga_t *svga); - -static void -gd5428_copy_pixel(gd5428_t *gd5428, svga_t *svga, uint8_t src, uint8_t dst); - -static void -gd5428_start_blit(gd5428_t *gd5428, svga_t *svga); - -static void gd5428_recalc_banking(gd5428_t *gd5428); -static void gd5428_recalc_mapping(gd5428_t *gd5428); - - -static void -gd5428_out(uint16_t addr, uint8_t val, void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - svga_t *svga = &gd5428->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) { - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr & 0x1f) { - case 6: /* cirrus unlock extensions */ - val &= 0x17; - if (val == 0x12) - svga->seqregs[6] = 0x12; - else - svga->seqregs[6] = 0x0f; - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ - gd5428->vclk_n[svga->seqaddr-0x0b] = val; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ - gd5428->vclk_d[svga->seqaddr-0x1b] = val; - break; - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); - break; - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); - break; - case 0x12: - svga->hwcursor.ena = val & 1; - break; - case 0x13: - svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); - break; - case 0x17: - svga->seqregs[0x17] = (svga->seqregs[0x17] & 0x38) | (val & 0xc7); - gd5428_recalc_mapping(gd5428); - break; - } - return; - } - break; - case 0x3C6: - if (gd5428->ramdac.state == 4) { - gd5428->ramdac.state = 0; - gd5428->ramdac.ctrl = val; - - if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { - switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - break; - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - case CIRRUS_SR7_BPP_16: - if (gd5428->ramdac.ctrl & 0x01) - svga->bpp = 16; - else - svga->bpp = 15; - break; - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - break; - case CIRRUS_SR7_BPP_32: - svga->bpp = 32; - break; - } - } - svga_recalctimings(svga); - return; - } - gd5428->ramdac.state = 0; - break; - case 0x3C7: case 0x3C8: - gd5428->ramdac.state = 0; - break; - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { - gd5428->ramdac.state = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - gd5428->ramdac.pal[svga->dac_write & 0xf].r = val & 63; - svga->dac_pos++; - break; - case 1: - gd5428->ramdac.pal[svga->dac_write & 0xf].g = val & 63; - svga->dac_pos++; - break; - case 2: - gd5428->ramdac.pal[svga->dac_write & 0xf].b = val & 63; - svga->dac_pos = 0; - svga->dac_write = (svga->dac_write + 1) & 255; - break; - } - return; - } - gd5428->ramdac.state = 0; - break; - case 0x3cf: - if (svga->gdcaddr == 0) { - svga->gdcreg[0] = val & 0xff; - return; - } - if (svga->gdcaddr == 1) { - svga->gdcreg[1] = val & 0xff; - return; - } - if (svga->gdcaddr == 5) { - svga->gdcreg[5] = val; - if (svga->gdcreg[0x0b] & 0x04) - svga->writemode = val & 7; - else - svga->writemode = val & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - return; - } - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - svga->gdcreg[6] = val; - gd5428_recalc_mapping(gd5428); - } else - svga->gdcreg[6] = val; - return; - } - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: - gd5428_recalc_banking(gd5428); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else { - svga->writemode = svga->gdcreg[5] & 3; - svga->gdcreg[0] &= 0x0f; - svga->gdcreg[1] &= 0x0f; - } - break; - case 0x20: - gd5428->blt.width = (gd5428->blt.width & 0xff00) | val; - break; - case 0x21: - gd5428->blt.width = (gd5428->blt.width & 0x00ff) | (val << 8); - break; - case 0x22: - gd5428->blt.height = (gd5428->blt.height & 0xff00) | val; - break; - case 0x23: - gd5428->blt.height = (gd5428->blt.height & 0x00ff) | (val << 8); - break; - case 0x24: - gd5428->blt.dst_pitch = (gd5428->blt.dst_pitch & 0xff00) | val; - break; - case 0x25: - gd5428->blt.dst_pitch = (gd5428->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x26: - gd5428->blt.src_pitch = (gd5428->blt.src_pitch & 0xff00) | val; - break; - case 0x27: - gd5428->blt.src_pitch = (gd5428->blt.src_pitch & 0x00ff) | (val << 8); - break; - case 0x28: - gd5428->blt.dst_addr = (gd5428->blt.dst_addr & 0xffff00) | val; - break; - case 0x29: - gd5428->blt.dst_addr = (gd5428->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x2a: - gd5428->blt.dst_addr = (gd5428->blt.dst_addr & 0x00ffff) | (val << 16); - break; - case 0x2c: - gd5428->blt.src_addr = (gd5428->blt.src_addr & 0xffff00) | val; - break; - case 0x2d: - gd5428->blt.src_addr = (gd5428->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x2e: - gd5428->blt.src_addr = (gd5428->blt.src_addr & 0x00ffff) | (val << 16); - break; - case 0x30: - gd5428->blt.mode = val; - break; - case 0x31: - gd5428->blt.status = val & ~0xf2; - if (val & 0x02) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - gd5428->blt.sys_tx = 1; - gd5428->blt.sys_cnt = 0; - gd5428->blt.sys_buf = 0; - gd5428->blt.pixel_cnt = gd5428->blt.scan_cnt = 0; - gd5428->blt.src_addr_backup = gd5428->blt.src_addr; - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr; - gd5428->blt.status |= 0x09; - } else - gd5428_start_blit(gd5428, &gd5428->svga); - } - break; - case 0x32: - gd5428->blt.rop = val; - break; - case 0x34: - gd5428->blt.trans_col = (gd5428->blt.trans_col & 0xff00) | val; - break; - case 0x35: - gd5428->blt.trans_col = (gd5428->blt.trans_col & 0x00ff) | (val << 8); - break; - case 0x36: - gd5428->blt.trans_mask = (gd5428->blt.trans_mask & 0xff00) | val; - break; - case 0x37: - gd5428->blt.trans_mask = (gd5428->blt.trans_mask & 0x00ff) | (val << 8); - break; - } - return; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - - -static uint8_t -gd5428_in(uint16_t addr, void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - svga_t *svga = &gd5428->svga; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c5: - if (svga->seqaddr > 5) { - switch (svga->seqaddr) { - case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd5428->vclk_n[svga->seqaddr-0x0b]; - case 0x0f: - return svga->seqregs[0x0f]; - case 0x15: - return gd5428->vram_code; - case 0x17: - return svga->seqregs[0x17]; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: - return gd5428->vclk_d[svga->seqaddr-0x1b]; - case 0x1f: - return svga->seqregs[0x1f]; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; - case 0x3C6: - if (gd5428->ramdac.state == 4) { - gd5428->ramdac.state = 0; - return gd5428->ramdac.ctrl; - } - gd5428->ramdac.state++; - break; - case 0x3C7: case 0x3C8: - gd5428->ramdac.state = 0; - break; - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { - gd5428->ramdac.state = 0; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - return gd5428->ramdac.pal[svga->dac_read & 0xf].r; - case 1: - svga->dac_pos++; - return gd5428->ramdac.pal[svga->dac_read & 0xf].g; - case 2: - svga->dac_pos=0; - svga->dac_read = (svga->dac_read + 1) & 255; - return gd5428->ramdac.pal[(svga->dac_read - 1) & 15].b; - } - } - gd5428->ramdac.state = 0; - break; - case 0x3cf: - if (svga->gdcaddr > 8) { - if (svga->gdcaddr == 0x31) - return gd5428->blt.status; - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) { - case 0x24: /*Attribute controller toggle readback (R)*/ - return svga->attrff << 7; - case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; - case 0x27: /*ID*/ - return svga->crtc[0x27]; /*GD542x/GD543x*/ - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - - -static void -gd5428_recalc_banking(gd5428_t *gd5428) -{ - svga_t *svga = &gd5428->svga; - - if (svga->gdcreg[0xb] & 0x20) - gd5428->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 14; - else - gd5428->bank[0] = svga->gdcreg[0x09] << 12; - - if (svga->gdcreg[0xb] & 0x01) { - if (svga->gdcreg[0xb] & 0x20) - gd5428->bank[1] = (svga->gdcreg[0x0a] & 0x7f) << 14; - else - gd5428->bank[1] = svga->gdcreg[0x0a] << 12; - } else - gd5428->bank[1] = gd5428->bank[0] + 0x8000; -} - - -static void -gd5428_recalc_mapping(gd5428_t *gd5428) -{ - svga_t *svga = &gd5428->svga; - - switch (svga->gdcreg[6] & 0x0C) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_disable(&gd5428->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if (svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5428->mmio_mapping, 0xb8000, 0x00100); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&gd5428->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&gd5428->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - } -} - - -static void -gd5428_recalctimings(svga_t *svga) -{ - gd5428_t *gd5428 = (gd5428_t *)svga->p; - uint8_t clocksel; - - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); - - svga->ma_latch = (svga->crtc[0x0c] << 8) - + svga->crtc[0x0d] - + ((svga->crtc[0x1b] & 0x01) << 16) - + ((svga->crtc[0x1b] & 0x0c) << 15) - + ((svga->crtc[0x1d] & 0x80) << 12); - - if (svga->crtc[0x1a] & 0x01) { - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vblankstart *= 2; - svga->vsyncstart *= 2; - svga->split *= 2; - } - - if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - break; - case 24: - svga->render = svga_render_24bpp_highres; - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } - } - - clocksel = (svga->miscout >> 2) & 3; - - if (!gd5428->vclk_n[clocksel] || !gd5428->vclk_d[clocksel]) - svga->clock = cpuclock / ((svga->miscout & 0x0c) ? 28322000.0 : 25175000.0); - else { - int n = gd5428->vclk_n[clocksel] & 0x7f; - int d = (gd5428->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd5428->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float)n / ((float)d * m))); - svga->clock = cpuclock / freq; - } -} - - -static void gd5428_hwcursor_draw(svga_t *svga, int displine) -{ - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int largecur = (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE); - int cursize = (largecur) ? 64 : 32; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; - - for (x = 0; x < cursize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr++; - } - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; -} - - -static void -gd5428_mem_writeb_mode4and5_8bpp(gd5428_t *gd5428, svga_t *svga, - uint8_t mode, - uint32_t offset, - uint32_t val) -{ - int x; - uint8_t *dst; - - dst = svga->vram + (offset & svga->vram_mask); - for (x = 0; x < 8; x++) { - if (val & 0x80) - { - *dst = svga->gdcreg[1]; - } - else - { - if (mode == 5) - *dst = svga->gdcreg[0]; - } - val <<= 1; - dst++; - } - svga->changedvram[(offset & svga->vram_mask) >> 12] = changeframecount; -} - - -static void -gd5428_mem_writeb_mode4and5_16bpp(gd5428_t *gd5428, svga_t *svga, - uint8_t mode, - uint32_t offset, - uint32_t val) -{ - int x; - uint8_t *dst; - - dst = svga->vram + (offset & svga->vram_mask); - for (x = 0; x < 8; x++) { - if (val & 0x80) - { - *dst = svga->gdcreg[1]; - *(dst + 1) = svga->gdcreg[0x11]; - } - else - { - if (mode == 5) - { - *dst = svga->gdcreg[0]; - *(dst + 1) = svga->gdcreg[0x10]; - } - } - val <<= 1; - dst += 2; - } - svga->changedvram[(offset & svga->vram_mask) >> 12] = changeframecount; -} - - -static void -gd5428_write(uint32_t addr, uint8_t val, void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - svga_t *svga = &gd5428->svga; - - if (gd5428->blt.sys_tx) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - gd5428->blt.sys_buf &= ~(0x000000ff); - gd5428->blt.sys_buf |= val; - gd5428_blit_byte(gd5428, svga); - gd5428->blt.sys_cnt = 0; - } else { - gd5428->blt.sys_buf &= ~(0x000000ff << (gd5428->blt.sys_cnt * 8)); - gd5428->blt.sys_buf |= (val << (gd5428->blt.sys_cnt * 8)); - gd5428->blt.sys_cnt++; - if(gd5428->blt.sys_cnt >= 4) { - gd5428_blit_dword(gd5428, svga); - gd5428->blt.sys_cnt = 0; - } - } - gd5428_recalc_mapping(gd5428); - return; - } - - addr &= svga->banked_mask; - - addr = (addr & 0x7fff) + gd5428->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4 || svga->writemode > 5) - svga_write_linear(addr, val, svga); - else { - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; - - egawrites++; - - svga->changedvram[addr >> 12]=changeframecount; - - if ((svga->gdcreg[0x0b] & 0x14) != 0x14) - gd5428_mem_writeb_mode4and5_8bpp(gd5428, svga, svga->writemode, addr << 3, val); - else - gd5428_mem_writeb_mode4and5_16bpp(gd5428, svga, svga->writemode, addr << 4, val); - } -} - - -static uint8_t -gd5428_read(uint32_t addr, void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - svga_t *svga = &gd5428->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5428->bank[(addr >> 15) & 1]; - return svga_read_linear(addr, svga); -} - - -/* non colour-expanded BitBLTs from system memory must be doubleword sized, extra bytes are ignored */ -static void -gd5428_blit_dword(gd5428_t *gd5428, svga_t *svga) -{ - /* TODO: add support for reverse direction */ - uint8_t x, pixel; - - for (x=0;x<32;x+=8) { - pixel = ((gd5428->blt.sys_buf & (0x000000ff << x)) >> x); - if(gd5428->blt.pixel_cnt <= gd5428->blt.width) - gd5428_copy_pixel(gd5428, svga, pixel, svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - gd5428->blt.dst_addr_backup++; - gd5428->blt.pixel_cnt++; - } - if (gd5428->blt.pixel_cnt > gd5428->blt.width) { - gd5428->blt.pixel_cnt = 0; - gd5428->blt.scan_cnt++; - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr + (gd5428->blt.dst_pitch*gd5428->blt.scan_cnt); - } - if (gd5428->blt.scan_cnt > gd5428->blt.height) { - gd5428->blt.sys_tx = 0; /* BitBLT complete */ - gd5428->blt.status &= ~0x0b; - gd5428_recalc_mapping(gd5428); - } -} - -/* colour-expanded BitBLTs from system memory are on a byte boundary, unused bits are ignored */ -static void -gd5428_blit_byte(gd5428_t *gd5428, svga_t *svga) -{ - /* TODO: add support for reverse direction */ - uint8_t x, pixel; - - for (x=0;x<8;x++) { - /* use GR0/1/10/11 background/foreground regs */ - if (gd5428->blt.dst_addr_backup & 1) - pixel = ((gd5428->blt.sys_buf & (0x00000001 << (7-x))) >> (7-x)) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - else - pixel = ((gd5428->blt.sys_buf & (0x00000001 << (7-x))) >> (7-x)) ? svga->gdcreg[1] : svga->gdcreg[0]; - if(gd5428->blt.pixel_cnt <= gd5428->blt.width - 1) - gd5428_copy_pixel(gd5428, svga, pixel, svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - gd5428->blt.dst_addr_backup++; - gd5428->blt.pixel_cnt++; - } - if (gd5428->blt.pixel_cnt > gd5428->blt.width) { - gd5428->blt.pixel_cnt = 0; - gd5428->blt.scan_cnt++; - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr + (gd5428->blt.dst_pitch*gd5428->blt.scan_cnt); - } - if(gd5428->blt.scan_cnt > gd5428->blt.height) { - gd5428->blt.sys_tx = 0; // BitBLT complete - gd5428->blt.status &= ~0x0b; - gd5428_recalc_mapping(gd5428); - } -} - - -static void -gd5428_copy_pixel(gd5428_t *gd5428, svga_t *svga, uint8_t src, uint8_t dst) -{ - svga->changedvram[(gd5428->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; - - switch (gd5428->blt.rop) { - case 0x00: dst = 0; break; - case 0x05: dst = src & dst; break; - case 0x06: dst = dst; break; - case 0x09: dst = src & ~dst; break; - case 0x0b: dst = ~ dst; break; - case 0x0d: dst = src; break; - case 0x0e: dst = 0xff; break; - case 0x50: dst = ~ src & dst; break; - case 0x59: dst = src ^ dst; break; - case 0x6d: dst = src | dst; break; - case 0x90: dst = ~(src | dst); break; - case 0x95: dst = ~(src ^ dst); break; - case 0xad: dst = src | ~dst; break; - case 0xd0: dst = ~src; break; - case 0xd6: dst = ~src | dst; break; - case 0xda: dst = ~(src & dst); break; - } - - /* handle transparency compare */ - if(gd5428->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { /* TODO: 16-bit compare */ - /* if ROP result matches the transparency colour, don't change the pixel */ - if((dst & (~gd5428->blt.trans_mask & 0xff)) == ((gd5428->blt.trans_col & 0xff) & (~gd5428->blt.trans_mask & 0xff))) - return; - } - - svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask] = dst; -} - - -static void -gd5428_start_blit(gd5428_t *gd5428, svga_t *svga) -{ - uint32_t x, y; - - gd5428->blt.src_addr_backup = gd5428->blt.src_addr; - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr; - - for (y=0;y<=gd5428->blt.height;y++) { - for (x=0;x<=gd5428->blt.width;x++) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) { - uint16_t pixel = (svga->vram[gd5428->blt.src_addr_backup & svga->vram_mask] >> (7-((x/2) % 8)) & 0x01) ? ((svga->gdcreg[0x11]<<8)|svga->gdcreg[1]) : ((svga->gdcreg[0x10]<<8)|svga->gdcreg[0]); - - if(gd5428->blt.dst_addr_backup & 1) - gd5428_copy_pixel(gd5428, svga, pixel >> 8, svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - else - gd5428_copy_pixel(gd5428, svga, pixel & 0xff, svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - if((x % 8) == 7 && !(gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY)) { /* don't increment if a pattern (it's only 8 bits) */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd5428->blt.src_addr_backup--; - else - gd5428->blt.src_addr_backup++; - } - } else { - uint8_t pixel = (svga->vram[gd5428->blt.src_addr_backup & svga->vram_mask] >> (7-(x % 8)) & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; - - gd5428_copy_pixel(gd5428, svga, pixel, svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - - if((x % 8) == 7 && !(gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY)) { /* don't increment if a pattern (it's only 8 bits) */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd5428->blt.src_addr_backup--; - else - gd5428->blt.src_addr_backup++; - } - } - } else { - gd5428_copy_pixel(gd5428, svga, svga->vram[gd5428->blt.src_addr_backup & svga->vram_mask], svga->vram[gd5428->blt.dst_addr_backup & svga->vram_mask]); - - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd5428->blt.src_addr_backup--; - else - gd5428->blt.src_addr_backup++; - } - - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd5428->blt.dst_addr_backup--; - else - gd5428->blt.dst_addr_backup++; - - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 8) == 7) { /* 8x8 pattern - reset pattern source location */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) /* colour expand */ - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (1 * (y % 8)); /* patterns are linear data */ - else if(svga->bpp == 15 || svga->bpp == 16) { - if(gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 16) == 15) - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (16 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (8 * (y % 8)); - } - } else { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 8) == 7) { /* 8x8 pattern - reset pattern source location */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) /* colour expand */ - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (1 * (y % 8)); // patterns are linear data - else if (svga->bpp == 15 || svga->bpp == 16) { - if(gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 16) == 15) - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (16 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (8 * (y % 8)); - } - } - } - - if (gd5428->blt.mode & CIRRUS_BLTMODE_BACKWARDS) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) { /* 8x8 pattern */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) /* colour expand */ - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (1 * (y % 8)); /* patterns are linear data */ - else if (svga->bpp == 15 || svga->bpp == 16) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 16) == 15) - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (16 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (8 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr - (gd5428->blt.src_pitch*(y+1)); - - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr - (gd5428->blt.dst_pitch*(y+1)); - } else { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) { /* 8x8 pattern */ - if (gd5428->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) /* colour expand */ - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (1 * (y % 8)); /* patterns are linear data */ - else if(svga->bpp == 15 || svga->bpp == 16) { - if (gd5428->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY && (x % 16) == 15) - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (16 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (8 * (y % 8)); - } else - gd5428->blt.src_addr_backup = gd5428->blt.src_addr + (gd5428->blt.src_pitch*(y+1)); - - gd5428->blt.dst_addr_backup = gd5428->blt.dst_addr + (gd5428->blt.dst_pitch*(y+1)); - } - } - - gd5428->blt.status &= ~0x02; - gd5428_recalc_mapping(gd5428); -} - - -static void -*gd5428_init(device_t *info) -{ - gd5428_t *gd5428 = malloc(sizeof(gd5428_t)); - svga_t *svga = &gd5428->svga; - int id = info->local; - memset(gd5428, 0, sizeof(gd5428_t)); - - rom_init(&gd5428->bios_rom, BIOS_GD5428_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - gd5428->vram_size = (2 << 20); /*2mb*/ - - svga_init(&gd5428->svga, gd5428, gd5428->vram_size, - gd5428_recalctimings, gd5428_in, gd5428_out, - gd5428_hwcursor_draw, NULL); - - mem_mapping_set_handler(&svga->mapping, gd5428_read, NULL, NULL, gd5428_write, NULL, NULL); - mem_mapping_set_p(&svga->mapping, gd5428); - - io_sethandler(0x03c0, 0x0020, gd5428_in, NULL, NULL, gd5428_out, NULL, NULL, gd5428); - - gd5428->vram_code = 3; - svga->seqregs[0x0f] = 0x18; /*2MB of memory*/ - svga->seqregs[0x17] = 0x38; /*ISA*/ - svga->seqregs[0x1f] = 0x22; - - svga->crtc[0x27] = id; - - svga->hwcursor.yoff = 32; - svga->hwcursor.xoff = 0; - - gd5428->vclk_n[0] = 0x4a; - gd5428->vclk_d[0] = 0x2b; - gd5428->vclk_n[1] = 0x5b; - gd5428->vclk_d[1] = 0x2f; - - gd5428->bank[1] = 0x8000; - - return gd5428; -} - - -static int -gd5428_available(void) -{ - return rom_present(BIOS_GD5428_PATH); -} - - -void -gd5428_close(void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - - svga_close(&gd5428->svga); - - free(gd5428); -} - - -void -gd5428_speed_changed(void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - - svga_recalctimings(&gd5428->svga); -} - - -void gd5428_force_redraw(void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - - gd5428->svga.fullchange = changeframecount; -} - - -void gd5428_add_status_info(char *s, int max_len, void *p) -{ - gd5428_t *gd5428 = (gd5428_t *)p; - - svga_add_status_info(s, max_len, &gd5428->svga); -} - - -device_t gd5428_device = -{ - "Cirrus Logic GD5428", - DEVICE_VLB, - CIRRUS_ID_CLGD5428, - gd5428_init, - gd5428_close, - NULL, - gd5428_available, - gd5428_speed_changed, - gd5428_force_redraw, - gd5428_add_status_info, - NULL -}; diff --git a/src/video/vid_cl5429.h b/src/video/vid_cl5429.h deleted file mode 100644 index a3e327f46..000000000 --- a/src/video/vid_cl5429.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern device_t gd5429_device; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c new file mode 100644 index 000000000..14d6702c5 --- /dev/null +++ b/src/video/vid_cl54xx.c @@ -0,0 +1,1413 @@ +/* + * 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 select Cirrus Logic cards (currently only + * CL-GD 5428 and 5429 are fully supported). + * + * Version: @(#)vid_cl_54xx.c 1.0.0 2018/02/18 + * + * Authors: Sarah Walker, + * Barry Rodewald, + * TheCollector1995, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2018 Barry Rodewald + * Copyright 2016-2018 TheCollector1995. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../cpu/cpu.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_svga_render.h" +#include "vid_cl54xx.h" + +#define BIOS_GD5428_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB (Cirrus Logic 5428)_v3.04.bin" +#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" + +#define CIRRUS_ID_CLGD5428 0x98 +#define CIRRUS_ID_CLGD5429 0x9c + +/* sequencer 0x07 */ +#define CIRRUS_SR7_BPP_VGA 0x00 +#define CIRRUS_SR7_BPP_SVGA 0x01 +#define CIRRUS_SR7_BPP_MASK 0x0e +#define CIRRUS_SR7_BPP_8 0x00 +#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 +#define CIRRUS_SR7_BPP_24 0x04 +#define CIRRUS_SR7_BPP_16 0x06 +#define CIRRUS_SR7_BPP_32 0x08 +#define CIRRUS_SR7_ISAADDR_MASK 0xe0 + +/* sequencer 0x12 */ +#define CIRRUS_CURSOR_SHOW 0x01 +#define CIRRUS_CURSOR_HIDDENPEL 0x02 +#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ + +/* control 0x30 */ +#define CIRRUS_BLTMODE_BACKWARDS 0x01 +#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 +#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 +#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 +#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 +#define CIRRUS_BLTMODE_COLOREXPAND 0x80 +#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 +#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 +#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 +#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 +#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 + + +typedef struct gd54xx_t +{ + mem_mapping_t mmio_mapping; + + svga_t svga; + + rom_t bios_rom; + + uint32_t vram_size; + uint8_t vram_code; + uint32_t vram_mask; + + uint8_t vclk_n[4]; + uint8_t vclk_d[4]; + uint32_t bank[2]; + + struct { + uint8_t state; + int ctrl; + PALETTE pal; + } ramdac; + + struct { + uint16_t fg_col, bg_col; + uint16_t width, height; + uint16_t dst_pitch, src_pitch; + uint32_t dst_addr, src_addr; + uint8_t mask, mode, rop; + uint8_t status; + uint16_t trans_col, trans_mask; + + uint32_t dst_addr_backup, src_addr_backup; + uint16_t width_backup, height_internal; + + int x_count, y_count; + int sys_tx; + uint8_t sys_cnt; + uint32_t sys_buf; + uint16_t pixel_cnt; + uint16_t scan_cnt; + } blt; +} gd54xx_t; + +static void +gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); + +static void +gd54xx_recalc_banking(gd54xx_t *gd54xx); + +static void +gd543x_recalc_mapping(gd54xx_t *gd54xx); + +static void +gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga); + +static void +gd54xx_out(uint16_t addr, uint8_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c4: + svga->seqaddr = val; + break; + case 0x3c5: + if (svga->seqaddr > 5) { + svga->seqregs[svga->seqaddr & 0x1f] = val; + switch (svga->seqaddr & 0x1f) { + case 6: /* cirrus unlock extensions */ + val &= 0x17; + if (val == 0x12) + svga->seqregs[6] = 0x12; + else + svga->seqregs[6] = 0x0f; + break; + case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ + gd54xx->vclk_n[svga->seqaddr-0x0b] = val; + break; + case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ + gd54xx->vclk_d[svga->seqaddr-0x1b] = val; + break; + case 0x10: case 0x30: case 0x50: case 0x70: + case 0x90: case 0xb0: case 0xd0: case 0xf0: + svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); + break; + case 0x11: case 0x31: case 0x51: case 0x71: + case 0x91: case 0xb1: case 0xd1: case 0xf1: + svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); + break; + case 0x12: + svga->hwcursor.ena = val & 1; + break; + case 0x13: + svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); + break; + case 0x17: + svga->seqregs[0x17] = (svga->seqregs[0x17] & 0x38) | (val & 0xc7); + gd543x_recalc_mapping(gd54xx); + break; + } + return; + } + break; + case 0x3C6: + if (gd54xx->ramdac.state == 4) { + gd54xx->ramdac.state = 0; + gd54xx->ramdac.ctrl = val; + + if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { + switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) { + case CIRRUS_SR7_BPP_8: + svga->bpp = 8; + break; + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + case CIRRUS_SR7_BPP_16: + if (gd54xx->ramdac.ctrl & 0x01) + svga->bpp = 16; + else + svga->bpp = 15; + break; + case CIRRUS_SR7_BPP_24: + svga->bpp = 24; + break; + case CIRRUS_SR7_BPP_32: + svga->bpp = 32; + break; + } + } + svga_recalctimings(svga); + return; + } + gd54xx->ramdac.state = 0; + break; + case 0x3C7: case 0x3C8: + gd54xx->ramdac.state = 0; + break; + case 0x3C9: + if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { + gd54xx->ramdac.state = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + gd54xx->ramdac.pal[svga->dac_write & 0xf].r = val & 63; + svga->dac_pos++; + break; + case 1: + gd54xx->ramdac.pal[svga->dac_write & 0xf].g = val & 63; + svga->dac_pos++; + break; + case 2: + gd54xx->ramdac.pal[svga->dac_write & 0xf].b = val & 63; + svga->dac_pos = 0; + svga->dac_write = (svga->dac_write + 1) & 255; + break; + } + return; + } + gd54xx->ramdac.state = 0; + break; + case 0x3cf: + if (svga->gdcaddr == 0) + gd543x_mmio_write(0x00, val, gd54xx); + if (svga->gdcaddr == 1) + gd543x_mmio_write(0x04, val, gd54xx); + + if (svga->gdcaddr == 5) { + svga->gdcreg[5] = val; + if (svga->gdcreg[0x0b] & 0x04) + svga->writemode = val & 7; + else + svga->writemode = val & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + return; + } + if (svga->gdcaddr > 8) { + svga->gdcreg[svga->gdcaddr & 0x3f] = val; + switch (svga->gdcaddr) { + case 0x09: case 0x0a: case 0x0b: + gd54xx_recalc_banking(gd54xx); + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; + else + svga->writemode = svga->gdcreg[5] & 3; + break; + + case 0x10: + gd543x_mmio_write(0x01, val, gd54xx); + break; + case 0x11: + gd543x_mmio_write(0x05, val, gd54xx); + break; + + case 0x20: + gd543x_mmio_write(0x08, val, gd54xx); + break; + case 0x21: + gd543x_mmio_write(0x09, val, gd54xx); + break; + case 0x22: + gd543x_mmio_write(0x0a, val, gd54xx); + break; + case 0x23: + gd543x_mmio_write(0x0b, val, gd54xx); + break; + case 0x24: + gd543x_mmio_write(0x0c, val, gd54xx); + break; + case 0x25: + gd543x_mmio_write(0x0d, val, gd54xx); + break; + case 0x26: + gd543x_mmio_write(0x0e, val, gd54xx); + break; + case 0x27: + gd543x_mmio_write(0x0f, val, gd54xx); + break; + + case 0x28: + gd543x_mmio_write(0x10, val, gd54xx); + break; + case 0x29: + gd543x_mmio_write(0x11, val, gd54xx); + break; + case 0x2a: + gd543x_mmio_write(0x12, val, gd54xx); + break; + + case 0x2c: + gd543x_mmio_write(0x14, val, gd54xx); + break; + case 0x2d: + gd543x_mmio_write(0x15, val, gd54xx); + break; + case 0x2e: + gd543x_mmio_write(0x16, val, gd54xx); + break; + + case 0x2f: + gd543x_mmio_write(0x17, val, gd54xx); + break; + case 0x30: + gd543x_mmio_write(0x18, val, gd54xx); + break; + + case 0x32: + gd543x_mmio_write(0x1a, val, gd54xx); + break; + + case 0x31: + gd543x_mmio_write(0x40, val, gd54xx); + break; + } + return; + } + break; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); +} + + +static uint8_t +gd54xx_in(uint16_t addr, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c5: + if (svga->seqaddr > 5) { + switch (svga->seqaddr) { + case 6: + return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + case 0x0b: case 0x0c: case 0x0d: case 0x0e: + return gd54xx->vclk_n[svga->seqaddr-0x0b]; + case 0x0f: + return svga->seqregs[0x0f]; + case 0x15: + return gd54xx->vram_code; + case 0x17: + return svga->seqregs[0x17]; + case 0x1b: case 0x1c: case 0x1d: case 0x1e: + return gd54xx->vclk_d[svga->seqaddr-0x1b]; + case 0x1f: + return svga->seqregs[0x1f]; + } + return svga->seqregs[svga->seqaddr & 0x3f]; + } + break; + case 0x3C6: + if (gd54xx->ramdac.state == 4) { + gd54xx->ramdac.state = 0; + return gd54xx->ramdac.ctrl; + } + gd54xx->ramdac.state++; + break; + case 0x3C7: case 0x3C8: + gd54xx->ramdac.state = 0; + break; + case 0x3C9: + if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { + gd54xx->ramdac.state = 0; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + return gd54xx->ramdac.pal[svga->dac_read & 0xf].r; + case 1: + svga->dac_pos++; + return gd54xx->ramdac.pal[svga->dac_read & 0xf].g; + case 2: + svga->dac_pos=0; + svga->dac_read = (svga->dac_read + 1) & 255; + return gd54xx->ramdac.pal[(svga->dac_read - 1) & 15].b; + } + } + gd54xx->ramdac.state = 0; + break; + case 0x3cf: + if (svga->gdcaddr > 8) { + return svga->gdcreg[svga->gdcaddr & 0x3f]; + } + break; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + switch (svga->crtcreg) { + case 0x24: /*Attribute controller toggle readback (R)*/ + return svga->attrff << 7; + case 0x26: /*Attribute controller index readback (R)*/ + return svga->attraddr & 0x3f; + case 0x27: /*ID*/ + return svga->crtc[0x27]; /*GD542x/GD543x*/ + } + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); +} + + +static void +gd54xx_recalc_banking(gd54xx_t *gd54xx) +{ + svga_t *svga = &gd54xx->svga; + + if (svga->gdcreg[0xb] & 0x20) + gd54xx->bank[0] = svga->gdcreg[0x09] << 14; + else + gd54xx->bank[0] = svga->gdcreg[0x09] << 12; + + if (svga->gdcreg[0xb] & 0x01) { + if (svga->gdcreg[0xb] & 0x20) + gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; + else + gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; + } else + gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; +} + + +static void +gd543x_recalc_mapping(gd54xx_t *gd54xx) +{ + svga_t *svga = &gd54xx->svga; + + switch (svga->gdcreg[6] & 0x0C) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&gd54xx->mmio_mapping); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + if (svga->seqregs[0x17] & 0x04) + mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_disable(&gd54xx->mmio_mapping); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_disable(&gd54xx->mmio_mapping); + svga->banked_mask = 0x7fff; + break; + } +} + + +static void +gd54xx_recalctimings(svga_t *svga) +{ + gd54xx_t *gd54xx = (gd54xx_t *)svga->p; + uint8_t clocksel; + + svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); + + svga->ma_latch = (svga->crtc[0x0c] << 8) + + svga->crtc[0x0d] + + ((svga->crtc[0x1b] & 0x01) << 16) + + ((svga->crtc[0x1b] & 0x0c) << 15) + + ((svga->crtc[0x1d] & 0x80) << 12); + + svga->interlace = (svga->crtc[0x1a] & 0x01); + + if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } + + clocksel = (svga->miscout >> 2) & 3; + + if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) + svga->clock = cpuclock / ((svga->miscout & 0x0c) ? 28322000.0 : 25175000.0); + else { + int n = gd54xx->vclk_n[clocksel] & 0x7f; + int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; + int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; + float freq = (14318184.0 * ((float)n / ((float)d * m))); + svga->clock = cpuclock / freq; + } + + svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; +} + + +static void +gd54xx_hwcursor_draw(svga_t *svga, int displine) +{ + int x; + uint8_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int largecur = (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE); + int cursize = (largecur) ? 64 : 32; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; + + for (x = 0; x < cursize; x += 8) { + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + for (xx = 0; xx < 8; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (dat[1] & 0x80) + ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] = 0; + if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] ^= 0xffffff; + } + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr++; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; +} + + +static void +gd5428_copy_pixel(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) +{ + uint8_t res = src; + svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; + + switch (gd54xx->blt.rop) { + case 0x00: res = 0; break; + case 0x05: res = src & dst; break; + case 0x06: res = dst; break; + case 0x09: res = src & ~dst; break; + case 0x0b: res = ~ dst; break; + case 0x0d: res = src; break; + case 0x0e: res = 0xff; break; + case 0x50: res = ~ src & dst; break; + case 0x59: res = src ^ dst; break; + case 0x6d: res = src | dst; break; + case 0x90: res = ~(src | dst); break; + case 0x95: res = ~(src ^ dst); break; + case 0xad: res = src | ~dst; break; + case 0xd0: res = ~src; break; + case 0xd6: res = ~src | dst; break; + case 0xda: res = ~(src & dst); break; + } + + /* handle transparency compare */ + if(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { /* TODO: 16-bit compare */ + /* if ROP result matches the transparency colour, don't change the pixel */ + if((res & (~gd54xx->blt.trans_mask & 0xff)) == ((gd54xx->blt.trans_col & 0xff) & (~gd54xx->blt.trans_mask & 0xff))) + return; + } + + svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask] = res; +} + + +/* non colour-expanded BitBLTs from system memory must be doubleword sized, extra bytes are ignored */ +static void +gd54xx_blit_dword(gd54xx_t *gd54xx, svga_t *svga) +{ + /* TODO: add support for reverse direction */ + uint8_t x, pixel; + + for (x=0;x<32;x+=8) { + pixel = ((gd54xx->blt.sys_buf & (0xff << x)) >> x); + if(gd54xx->blt.pixel_cnt <= gd54xx->blt.width) + gd5428_copy_pixel(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); + gd54xx->blt.dst_addr_backup++; + gd54xx->blt.pixel_cnt++; + } + if (gd54xx->blt.pixel_cnt > gd54xx->blt.width) { + gd54xx->blt.pixel_cnt = 0; + gd54xx->blt.scan_cnt++; + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch*gd54xx->blt.scan_cnt); + } + if (gd54xx->blt.scan_cnt > gd54xx->blt.height) { + gd54xx->blt.sys_tx = 0; /* BitBLT complete */ + gd543x_recalc_mapping(gd54xx); + } +} + + +static void +gd54xx_blt_write_w(uint32_t addr, uint16_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + gd54xx_start_blit(val, 16, gd54xx, &gd54xx->svga); +} + + +static void +gd54xx_blt_write_l(uint32_t addr, uint32_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + gd54xx_start_blit(val, 32, gd54xx, &gd54xx->svga); +} + + +static void gd54xx_write_linear(uint32_t addr, uint8_t val, gd54xx_t *gd54xx); + + +static void +gd54xx_write(uint32_t addr, uint8_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + + if (gd54xx->blt.sys_tx) { + if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { + gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); + gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); + gd54xx->blt.sys_cnt++; + if(gd54xx->blt.sys_cnt >= 4) { + gd54xx_blit_dword(gd54xx, svga); + gd54xx->blt.sys_cnt = 0; + } + } + return; + } + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + gd54xx_write_linear(addr, val, gd54xx); +} + + +static void +gd54xx_writew(uint32_t addr, uint16_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + + if (svga->writemode < 4) + svga_writew_linear(addr, val, svga); + else { + gd54xx_write_linear(addr, val, gd54xx); + gd54xx_write_linear(addr+1, val >> 8, gd54xx); + } +} + + +static void +gd54xx_writel(uint32_t addr, uint32_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + + if (svga->writemode < 4) + svga_writel_linear(addr, val, svga); + else { + gd54xx_write_linear(addr, val, gd54xx); + gd54xx_write_linear(addr+1, val >> 8, gd54xx); + gd54xx_write_linear(addr+2, val >> 16, gd54xx); + gd54xx_write_linear(addr+3, val >> 24, gd54xx); + } +} + + +static void +gd54xx_write_linear(uint32_t addr, uint8_t val, gd54xx_t *gd54xx) +{ + svga_t *svga = &gd54xx->svga; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; + int i; + uint8_t j; + + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; + + egawrites++; + + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else + addr <<= 2; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12]=changeframecount; + + switch (svga->writemode) { + case 4: + if (svga->gdcreg[0xb] & 0x10) { + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; + + for (i = 0; i < 8; i++) { + if (val & svga->seqregs[2] & (0x80 >> i)) { + svga->vram[addr + (i << 1)] = svga->gdcreg[1]; + svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; + } + } + } else { + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; + + for (i = 0; i < 8; i++) { + if (val & svga->seqregs[2] & (0x80 >> i)) + svga->vram[addr + i] = svga->gdcreg[1]; + } + } + break; + + case 5: + if (svga->gdcreg[0xb] & 0x10) + { + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; + + for (i = 0; i < 8; i++) { + j = (0x80 >> i); + if (svga->seqregs[2] & j) { + svga->vram[addr + (i << 1)] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + (i << 1) + 1] = (val & j) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + } + } + else + { + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; + + for (i = 0; i < 8; i++) { + j = (0x80 >> i); + if (svga->seqregs[2] & j) + svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; + } + } + break; + + case 1: + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; + break; + case 0: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || (svga->seqregs[7] & 1))) { + if (writemask2 & 1) svga->vram[addr] = val; + if (writemask2 & 2) svga->vram[addr | 0x1] = val; + if (writemask2 & 4) svga->vram[addr | 0x2] = val; + if (writemask2 & 8) svga->vram[addr | 0x3] = val; + } else { + if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else vala = val; + if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else valb = val; + if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else valc = val; + if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else vald = val; + + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 2: + if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { + if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; + + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } +} + + +static uint8_t +gd54xx_read(uint32_t addr, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_read_linear(addr, svga); +} + + +static uint16_t +gd54xx_readw(uint32_t addr, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_readw_linear(addr, svga); +} + + +static uint32_t +gd54xx_readl(uint32_t addr, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_readl_linear(addr, svga); +} + + +static void +gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + switch (addr & 0xff) { + case 0x00: + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; + break; + case 0x01: + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); + break; + + case 0x04: + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; + break; + case 0x05: + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); + break; + + case 0x08: + gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; + break; + case 0x09: + gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); + break; + case 0x0a: + gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; + break; + case 0x0b: + gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); + break; + case 0x0c: + gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; + break; + case 0x0d: + gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); + break; + case 0x0e: + gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; + break; + case 0x0f: + gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); + break; + + case 0x10: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; + break; + case 0x11: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); + break; + case 0x12: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); + break; + + case 0x14: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; + break; + case 0x15: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); + break; + case 0x16: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); + break; + + case 0x17: + gd54xx->blt.mask = val; + break; + case 0x18: + gd54xx->blt.mode = val; + break; + + case 0x1a: + gd54xx->blt.rop = val; + break; + + case 0x40: + if (val & 0x02) { + if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { + gd54xx->blt.sys_tx = 1; + gd54xx->blt.sys_cnt = 0; + gd54xx->blt.sys_buf = 0; + gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; + } else + gd54xx_start_blit(0, -1, gd54xx, &gd54xx->svga); + } + break; + } +} + + +static uint8_t +gd543x_mmio_read(uint32_t addr, void *p) +{ + switch (addr & 0xff) { + case 0x40: /*BLT status*/ + return 0; + } + return 0xff; /*All other registers read-only*/ +} + + +static void +gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) +{ + int blt_mask = gd54xx->blt.mask & 7; + + if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) + blt_mask *= 2; + + if (count == -1) { + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; + gd54xx->blt.width_backup = gd54xx->blt.width; + gd54xx->blt.height_internal = gd54xx->blt.height; + gd54xx->blt.x_count = 0; + if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) + gd54xx->blt.y_count = gd54xx->blt.src_addr & 7; + else + gd54xx->blt.y_count = 0; + + if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { + mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); + mem_mapping_set_p(&svga->mapping, gd54xx); + return; + } else if (gd54xx->blt.mode != CIRRUS_BLTMODE_MEMSYSSRC) { + mem_mapping_set_handler(&svga->mapping, gd54xx_read, NULL, NULL, gd54xx_write, NULL, NULL); + mem_mapping_set_p(&gd54xx->svga.mapping, gd54xx); + gd543x_recalc_mapping(gd54xx); + } + } else if (gd54xx->blt.height_internal == 0xffff) + return; + + while (count) { + uint8_t src = 0, dst; + int mask = 0; + + if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { + src = (cpu_dat & 0x80) ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + mask = cpu_dat & 0x80; + cpu_dat <<= 1; + count--; + } + } else { + switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { + case 0x00: + src = svga->vram[gd54xx->blt.src_addr & svga->vram_mask]; + gd54xx->blt.src_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); + mask = 1; + break; + case CIRRUS_BLTMODE_PATTERNCOPY: + if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; + else + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; + mask = 1; + break; + case CIRRUS_BLTMODE_COLOREXPAND: + if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) { + mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); + if (gd54xx->blt.dst_addr & 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + } else { + mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + } + break; + case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: + if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) { + mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); + if (gd54xx->blt.dst_addr & 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + } else { + mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + } + break; + } + count--; + } + dst = svga->vram[gd54xx->blt.dst_addr & svga->vram_mask]; + svga->changedvram[(gd54xx->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; + + switch (gd54xx->blt.rop) { + case 0x00: dst = 0; break; + case 0x05: dst = src & dst; break; + case 0x06: dst = dst; break; + case 0x09: dst = src & ~dst; break; + case 0x0b: dst = ~ dst; break; + case 0x0d: dst = src; break; + case 0x0e: dst = 0xff; break; + case 0x50: dst = ~ src & dst; break; + case 0x59: dst = src ^ dst; break; + case 0x6d: dst = src | dst; break; + case 0x90: dst = ~(src | dst); break; + case 0x95: dst = ~(src ^ dst); break; + case 0xad: dst = src | ~dst; break; + case 0xd0: dst = ~src; break; + case 0xd6: dst = ~src | dst; break; + case 0xda: dst = ~(src & dst); break; + } + + if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && + !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) + svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; + + gd54xx->blt.dst_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); + + gd54xx->blt.x_count++; + if (gd54xx->blt.x_count == ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) ? 16 : 8)) { + gd54xx->blt.x_count = 0; + if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) + gd54xx->blt.src_addr++; + } + + gd54xx->blt.width--; + + if (gd54xx->blt.width == 0xffff) { + gd54xx->blt.width = gd54xx->blt.width_backup; + + gd54xx->blt.dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.dst_pitch : gd54xx->blt.dst_pitch); + + switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { + case 0x00: + gd54xx->blt.src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.src_pitch : gd54xx->blt.src_pitch); + break; + case CIRRUS_BLTMODE_COLOREXPAND: + if (gd54xx->blt.x_count != 0) + gd54xx->blt.src_addr++; + break; + } + + gd54xx->blt.x_count = 0; + if (gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) + gd54xx->blt.y_count = (gd54xx->blt.y_count - 1) & 7; + else + gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) & 7; + + gd54xx->blt.height_internal--; + if (gd54xx->blt.height_internal == 0xffff) { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { + mem_mapping_set_handler(&svga->mapping, gd54xx_read, NULL, NULL, gd54xx_write, NULL, NULL); + mem_mapping_set_p(&svga->mapping, gd54xx); + gd543x_recalc_mapping(gd54xx); + } + return; + } + + if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) + return; + } + } +} + + +static void +*gd54xx_init(device_t *info) +{ + gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); + svga_t *svga = &gd54xx->svga; + int id = info->local; + wchar_t *romfn = NULL; + memset(gd54xx, 0, sizeof(gd54xx_t)); + + switch (id) { + case CIRRUS_ID_CLGD5428: + romfn = BIOS_GD5428_PATH; + break; + + case CIRRUS_ID_CLGD5429: + romfn = BIOS_GD5429_PATH; + break; + } + + gd54xx->vram_size = device_get_config_int("memory"); + gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; + + rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, + gd54xx_recalctimings, gd54xx_in, gd54xx_out, + gd54xx_hwcursor_draw, NULL); + + mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); + mem_mapping_set_p(&svga->mapping, gd54xx); + + mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, NULL, NULL, gd543x_mmio_write, NULL, NULL, NULL, 0, gd54xx); + + io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + + if (gd54xx->vram_size == (2 << 20)) { + gd54xx->vram_code = 3; + svga->seqregs[0x0f] = 0x18; /*2MB of memory*/ + svga->seqregs[0x17] = 0x38; /*ISA, win3.1 drivers require so*/ + svga->seqregs[0x1f] = 0x22; + } else { + gd54xx->vram_code = 2; + svga->seqregs[0x0f] = 0x10; /*1MB of memory*/ + svga->seqregs[0x17] = 0x38; /*ISA, win3.1 drivers require so*/ + svga->seqregs[0x1f] = 0x22; + } + + svga->crtc[0x27] = id; + + svga->hwcursor.yoff = 32; + svga->hwcursor.xoff = 0; + + gd54xx->vclk_n[0] = 0x4a; + gd54xx->vclk_d[0] = 0x2b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + + gd54xx->bank[1] = 0x8000; + + return gd54xx; +} + + +static int +gd5428_available(void) +{ + return rom_present(BIOS_GD5428_PATH); +} + + +static int +gd5429_available(void) +{ + return rom_present(BIOS_GD5429_PATH); +} + + +void +gd54xx_close(void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + svga_close(&gd54xx->svga); + + free(gd54xx); +} + + +void +gd54xx_speed_changed(void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + svga_recalctimings(&gd54xx->svga); +} + + +void +gd54xx_force_redraw(void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + gd54xx->svga.fullchange = changeframecount; +} + + +void +gd54xx_add_status_info(char *s, int max_len, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + svga_add_status_info(s, max_len, &gd54xx->svga); +} + + +static device_config_t gd542x_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, + { + .type = -1 + } +}; + + +device_t gd5428_device = +{ + "Cirrus Logic GD5428", + DEVICE_VLB, + CIRRUS_ID_CLGD5428, + gd54xx_init, + gd54xx_close, + NULL, + gd5428_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd542x_config +}; + + +device_t gd5429_device = +{ + "Cirrus Logic GD5429", + DEVICE_VLB, + CIRRUS_ID_CLGD5429, + gd54xx_init, + gd54xx_close, + NULL, + gd5429_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd542x_config +}; diff --git a/src/video/vid_cl5428.h b/src/video/vid_cl54xx.h similarity index 76% rename from src/video/vid_cl5428.h rename to src/video/vid_cl54xx.h index e61fee4ab..7a64cbac9 100644 --- a/src/video/vid_cl5428.h +++ b/src/video/vid_cl54xx.h @@ -2,3 +2,4 @@ see COPYING for more details */ extern device_t gd5428_device; +extern device_t gd5429_device; diff --git a/src/video/vid_cl_gd.c b/src/video/vid_cl_gd.c deleted file mode 100644 index 00fb58c4e..000000000 --- a/src/video/vid_cl_gd.c +++ /dev/null @@ -1,1174 +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 select Cirrus Logic cards. - * - * Version: @(#)vid_cl_gd.c 1.0.5 2018/02/03 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl_ramdac.h" -#include "vid_cl_gd.h" -#include "vid_cl_gd_blit.h" - - -#define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.rom" -#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_PATH L"roms/video/cirruslogic/pci.bin" -#define BIOS_GD5430VL_PATH L"roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5434_PATH L"roms/video/cirruslogic/japan.bin" -#define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" -#define BIOS_GD5440_PATH L"roms/video/cirruslogic/5440bios.bin" -#define BIOS_GD5446_PATH L"roms/video/cirruslogic/5446bv.vbi" -#define BIOS_GD6235_PATH L"roms/video/cirruslogic/vga6235.rom" - - -void cirrus_update_bank_ptr(clgd_t *clgd, uint8_t bank_index); -void clgd_recalctimings(svga_t *svga); - -void svga_write_cirrus(uint32_t addr, uint8_t val, void *p); -void svga_write_cirrus_linear(uint32_t addr, uint8_t val, void *p); -void svga_write_cirrus_linear_bitblt(uint32_t addr, uint8_t val, void *p); -uint8_t svga_read_cirrus(uint32_t addr, void *p); -uint8_t svga_read_cirrus_linear(uint32_t addr, void *p); -uint8_t svga_read_cirrus_linear_bitblt(uint32_t addr, void *p); - - -void clgd_out(uint16_t addr, uint8_t val, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - // pclog("clgd out %04X %02X\n", addr, val); - - switch (addr) - { - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) - { - old = svga->seqregs[svga->seqaddr & 0x1f]; - switch (svga->seqaddr & 0x1f) - { - case 0x06: - val &= 0x17; - if (val == 0x12) - { - svga->seqregs[svga->seqaddr & 0x1f] = 0x12; - } - else - { - svga->seqregs[svga->seqaddr & 0x1f] = 0xf; - } - break; - - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->seqregs[0x10] = val; - svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); - // pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); - break; - - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->seqregs[0x11] = val; - svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); - // pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); - break; - - case 0x07: - cirrus_update_memory_access(clgd); - clgd_recalctimings(svga); - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - case 0x14: case 0x15: case 0x16: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - svga->seqregs[svga->seqaddr & 0x1f] = val; - break; - - case 0x13: - svga->seqregs[svga->seqaddr & 0x1f] = val; - svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); - // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); - break; - - case 0x12: - svga->seqregs[svga->seqaddr & 0x1f] = val; - svga->hwcursor.ena = val & 1; - // pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); - break; - - case 0x17: - old = svga->seqregs[svga->seqaddr & 0x1f]; - svga->seqregs[svga->seqaddr & 0x1f] = (svga->seqregs[svga->seqaddr & 0x1f] & 0x38) | (val & 0xc7); - cirrus_update_memory_access(clgd); - break; - } - return; - } - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - cl_ramdac_out(addr, val, &clgd->ramdac, clgd, svga); - return; - - case 0x3cf: - if (svga->gdcaddr == 5) - { - svga->gdcreg[5] = val & 0x7f; - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - cirrus_update_memory_access(clgd); - svga_out(addr, val, svga); - return; - } - if (svga->gdcaddr == 6) - { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) - { - svga->gdcreg[6] = val; - cirrus_update_memory_access(clgd); - } - svga->gdcreg[6] = val; - return; - } - if (svga->gdcaddr > 8) - { - switch (svga->gdcaddr) - { - case 0x09: case 0x0A: case 0x0B: - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - cirrus_update_bank_ptr(clgd, 0); - cirrus_update_bank_ptr(clgd, 1); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - cirrus_update_memory_access(clgd); - break; - - case 0x21: case 0x23: case 0x25: case 0x27: - svga->gdcreg[svga->gdcaddr & 0x3f] = val & 0x1f; - break; - - case 0x2a: - svga->gdcreg[svga->gdcaddr & 0x3f] = val & 0x3f; - /* if auto start mode, starts bit blt now */ - if (svga->gdcreg[0x31] & CIRRUS_BLT_AUTOSTART) cirrus_bitblt_start(clgd, svga); - break; - - case 0x2e: - svga->gdcreg[svga->gdcaddr & 0x3f] = val & 0x3f; - break; - - case 0x31: - cirrus_write_bitblt(clgd, svga, val); - break; - - default: - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - break; - } - return; - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - if ((svga->crtcreg != 0x22) && (svga->crtcreg != 0x24) && (svga->crtcreg != 0x26) && (svga->crtcreg != 0x27)) svga->crtc[svga->crtcreg] = val; - if ((svga->crtcreg == 0x22) || (svga->crtcreg == 0x24) || (svga->crtcreg == 0x26) || (svga->crtcreg == 0x27)) return; - - if (old != val) - { - if (svga->crtcreg == 0x1b) - { - svga->vram_display_mask = (val & 2) ? (clgd->vram_size - 1) : 0x3ffff; - clgd->linear_mmio_mask = (val & 2) ? (clgd->vram_size - 256) : (0x40000 - 256); - } - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t clgd_in(uint16_t addr, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - - if ((((addr & 0xfff0) == 0x3d0) || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) - addr ^= 0x60; - - // if (addr != 0x3da) pclog("IN clgd %04X\n", addr); - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr > 5) - { - switch (svga->seqaddr) - { - case 0x06: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - return svga->seqregs[0x10]; - - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - return svga->seqregs[0x11]; - - case 0x15: - return clgd->vram_code; - - case 0x05: case 0x07: case 0x08: case 0x09: - case 0x0a: case 0x0b: case 0x0c: case 0x0d: - case 0x0e: case 0x0f: case 0x12: case 0x13: - case 0x14: case 0x16: case 0x17: case 0x18: - case 0x19: case 0x1a: case 0x1b: case 0x1c: - case 0x1d: case 0x1e: case 0x1f: - return svga->seqregs[svga->seqaddr]; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; - - case 0x3cf: - if (svga->gdcaddr >= 0x3a) - { - return 0xff; - } - if (svga->gdcaddr > 8) - { - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; - - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: -// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - return cl_ramdac_in(addr, &clgd->ramdac, clgd, svga); - - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) - { - case 0x24: /*Attribute controller toggle readback (R)*/ - return svga->attrff << 7; - case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -/*************************************** - * - * bank memory - * - ***************************************/ -void cirrus_update_bank_ptr(clgd_t *clgd, uint8_t bank_index) -{ - svga_t *svga = &clgd->svga; - - uint32_t offset; - uint32_t limit; - - if ((svga->gdcreg[0x0b] & 0x01) != 0) /* dual bank */ - offset = svga->gdcreg[0x09 + bank_index]; - else /* single bank */ - offset = svga->gdcreg[0x09]; - - if ((svga->gdcreg[0x0b] & 0x20) != 0) - offset <<= 14; - else - offset <<= 12; - - if (clgd->vram_size <= offset) - limit = 0; - else - limit = clgd->vram_size - offset; - - if (((svga->gdcreg[0x0b] & 0x01) == 0) && (bank_index != 0)) { - if (limit > 0x8000) { - offset += 0x8000; - limit -= 0x8000; - } else { - limit = 0; - } - } - - if (limit > 0) { - clgd->bank[bank_index] = offset; - clgd->limit[bank_index] = limit; - } else { - clgd->bank[bank_index] = 0; - clgd->limit[bank_index] = 0; - } -} - -void clgd_recalctimings(svga_t *svga) -{ - clgd_t *clgd = (clgd_t *)svga->p; - - uint32_t iWidth, iHeight; - uint8_t iDispBpp; - - svga->ma_latch = (svga->crtc[0x0c] << 8) - + svga->crtc[0x0d] - + ((svga->crtc[0x1b] & 0x01) << 16) - + ((svga->crtc[0x1b] & 0x0c) << 15) - + ((svga->crtc[0x1d] & 0x80) << 12); - svga->ma_latch <<= 2; - - iHeight = 1 + svga->crtc[0x12] - + ((svga->crtc[0x07] & 0x02) << 7) - + ((svga->crtc[0x07] & 0x40) << 3); - - if ((svga->crtc[0x1a] & 0x01) > 0) { - iHeight <<= 1; - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vblankstart *= 2; - svga->vsyncstart *= 2; - svga->split *= 2; - } - - iWidth = (svga->crtc[0x01] + 1) * 8; - iDispBpp = 4; - - if ((svga->seqregs[0x07] & 0x1) == CIRRUS_SR7_BPP_SVGA) - { - pclog("Cirrus SVGA extended sequencer mode %x\n", svga->seqregs[0x07]); - switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) - { - case CIRRUS_SR7_BPP_8: - iDispBpp = 8; - svga->render = svga_render_8bpp_highres; - break; - - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - case CIRRUS_SR7_BPP_16: - case 0x7: - if (clgd->ramdac.ctrl & 0x1) - { - iDispBpp = 16; - svga->render = svga_render_16bpp_highres; - } - else - { - iDispBpp = 15; - svga->render = svga_render_15bpp_highres; - } - break; - - case 0x3: - case CIRRUS_SR7_BPP_24: - case 0x5: - case 0xe: - iDispBpp = 24; - svga->render = svga_render_24bpp_highres; - break; - - case CIRRUS_SR7_BPP_32: - iDispBpp = 32; - svga->render = svga_render_32bpp_highres; - break; - } - } - - if ((iWidth != svga->video_res_x) || (iHeight != svga->video_res_y) - || (iDispBpp != svga->bpp)) { - pclog("Cirrus switched to %u x %u x %u\n", iWidth, iHeight, iDispBpp); - } - - svga->video_res_x = iWidth; - svga->video_res_y = iHeight; - svga->bpp = iDispBpp; - // pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); -} - -static void clgd_hwcursor_draw(svga_t *svga, int displine) -{ - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int largecur = (svga->seqregs[0x12] & 4); - int cursize = (largecur) ? 64 : 32; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - for (x = 0; x < cursize; x += 8) - { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) - { - if (offset >= svga->hwcursor_latch.x) - { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr++; - } -} - -void cirrus_update_memory_access(clgd_t *clgd) -{ - svga_t *svga = &clgd->svga; - - if ((svga->seqregs[0x17] & 0x44) == 0x44) - { - goto generic_io; - } - else if (clgd->src_ptr != clgd->src_ptr_end) - { - goto generic_io; - } - else - { - if ((svga->gdcreg[0x0B] & 0x14) == 0x14) - { - goto generic_io; - } - else if (svga->gdcreg[0x0B] & 0x02) - { - goto generic_io; - } - - svga->writemode = svga->gdcreg[0x05] & 7; - if (svga->writemode < 4 || svga->writemode > 5 || ((svga->gdcreg[0x0B] & 0x4) == 0)) - { - //pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); - switch (svga->gdcreg[6] & 0x0C) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&clgd->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if (svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&clgd->mmio_mapping, 0xb8000, 0x00100); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&clgd->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&clgd->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - } - } - else - { -generic_io: - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&clgd->mmio_mapping); - } - } -} - -static void svga_write_mode45_8bpp(clgd_t *clgd, uint8_t mode, uint32_t offset, uint8_t mem_value) -{ - int x; - uint8_t val = mem_value; - uint8_t *dst; - svga_t *svga = &clgd->svga; - - offset &= svga->decode_mask; - if (offset >= svga->vram_max) - return; - offset &= svga->vram_mask; - - dst = &(svga->vram[offset]); - - svga->changedvram[offset >> 12] = changeframecount; - - for (x = 0; x < 8; x++) - { - if (val & 0x80) - { - *dst = clgd->blt.fg_col; - } - else - { - *dst = clgd->blt.bg_col; - } - val <<= 1; - dst++; - } -} - -static void svga_write_mode45_16bpp(clgd_t *clgd, unsigned mode, unsigned offset, uint32_t mem_value) -{ - int x; - unsigned val = mem_value; - uint8_t *dst; - svga_t *svga = &clgd->svga; - - offset &= svga->decode_mask; - if (offset >= svga->vram_max) - return; - offset &= svga->vram_mask; - - dst = &(svga->vram[offset]); - - svga->changedvram[offset >> 12] = changeframecount; - - for (x = 0; x < 8; x++) - { - if (val & 0x80) - { - *dst = clgd->blt.fg_col; - *(dst + 1) = svga->gdcreg[0x11]; - } - else - { - *dst = clgd->blt.bg_col; - *(dst + 1) = svga->gdcreg[0x10]; - } - val <<= 1; - dst += 2; - } -} - -static uint8_t cirrus_mmio_blt_read(uint32_t address, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - uint8_t value; - - switch(address & 0xff) - { - case (CIRRUS_MMIO_BLTBGCOLOR + 0): - value = svga->gdcreg[0x00]; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 1): - value = svga->gdcreg[0x10]; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 2): - value = svga->gdcreg[0x12]; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 3): - value = svga->gdcreg[0x14]; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 0): - value = svga->gdcreg[0x01]; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 1): - value = svga->gdcreg[0x11]; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 2): - value = svga->gdcreg[0x13]; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 3): - value = svga->gdcreg[0x15]; - break; - case (CIRRUS_MMIO_BLTWIDTH + 0): - value = svga->gdcreg[0x20]; - break; - case (CIRRUS_MMIO_BLTWIDTH + 1): - value = svga->gdcreg[0x21]; - break; - case (CIRRUS_MMIO_BLTHEIGHT + 0): - value = svga->gdcreg[0x22]; - break; - case (CIRRUS_MMIO_BLTHEIGHT + 1): - value = svga->gdcreg[0x23]; - break; - case (CIRRUS_MMIO_BLTDESTPITCH + 0): - value = svga->gdcreg[0x24]; - break; - case (CIRRUS_MMIO_BLTDESTPITCH + 1): - value = svga->gdcreg[0x25]; - break; - case (CIRRUS_MMIO_BLTSRCPITCH + 0): - value = svga->gdcreg[0x26]; - break; - case (CIRRUS_MMIO_BLTSRCPITCH + 1): - value = svga->gdcreg[0x27]; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 0): - value = svga->gdcreg[0x28]; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 1): - value = svga->gdcreg[0x29]; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 2): - value = svga->gdcreg[0x2a]; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 0): - value = svga->gdcreg[0x2c]; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 1): - value = svga->gdcreg[0x2d]; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 2): - value = svga->gdcreg[0x2e]; - break; - case (CIRRUS_MMIO_BLTWRITEMASK): - value = svga->gdcreg[0x2f]; - break; - case (CIRRUS_MMIO_BLTMODE): - value = svga->gdcreg[0x30]; - break; - case (CIRRUS_MMIO_BLTROP): - value = svga->gdcreg[0x32]; - break; - case (CIRRUS_MMIO_BLTMODEEXT): - value = svga->gdcreg[0x33]; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): - value = svga->gdcreg[0x34]; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): - value = svga->gdcreg[0x35]; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): - value = svga->gdcreg[0x38]; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): - value = svga->gdcreg[0x39]; - break; - default: - value = 0xff; - break; - } - - return value; -} - -static void cirrus_mmio_blt_write(uint32_t address, uint8_t value, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - - switch(address & 0xff) - { - case (CIRRUS_MMIO_BLTBGCOLOR + 0): - svga->gdcreg[0x00] = value; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 1): - svga->gdcreg[0x10] = value; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 2): - svga->gdcreg[0x12] = value; - break; - case (CIRRUS_MMIO_BLTBGCOLOR + 3): - svga->gdcreg[0x14] = value; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 0): - svga->gdcreg[0x01] = value; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 1): - svga->gdcreg[0x11] = value; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 2): - svga->gdcreg[0x13] = value; - break; - case (CIRRUS_MMIO_BLTFGCOLOR + 3): - svga->gdcreg[0x15] = value; - break; - case (CIRRUS_MMIO_BLTWIDTH + 0): - svga->gdcreg[0x20] = value; - break; - case (CIRRUS_MMIO_BLTWIDTH + 1): - svga->gdcreg[0x21] = value; - break; - case (CIRRUS_MMIO_BLTHEIGHT + 0): - svga->gdcreg[0x22] = value; - break; - case (CIRRUS_MMIO_BLTHEIGHT + 1): - svga->gdcreg[0x23] = value; - break; - case (CIRRUS_MMIO_BLTDESTPITCH + 0): - svga->gdcreg[0x24] = value; - break; - case (CIRRUS_MMIO_BLTDESTPITCH + 1): - svga->gdcreg[0x25] = value; - break; - case (CIRRUS_MMIO_BLTSRCPITCH + 0): - svga->gdcreg[0x26] = value; - break; - case (CIRRUS_MMIO_BLTSRCPITCH + 1): - svga->gdcreg[0x27] = value; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 0): - svga->gdcreg[0x28] = value; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 1): - svga->gdcreg[0x29] = value; - break; - case (CIRRUS_MMIO_BLTDESTADDR + 2): - svga->gdcreg[0x2a] = value; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 0): - svga->gdcreg[0x2c] = value; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 1): - svga->gdcreg[0x2d] = value; - break; - case (CIRRUS_MMIO_BLTSRCADDR + 2): - svga->gdcreg[0x2e] = value; - break; - case (CIRRUS_MMIO_BLTWRITEMASK): - svga->gdcreg[0x2f] = value; - break; - case (CIRRUS_MMIO_BLTMODE): - svga->gdcreg[0x30] = value; - break; - case (CIRRUS_MMIO_BLTROP): - svga->gdcreg[0x32] = value; - break; - case (CIRRUS_MMIO_BLTMODEEXT): - svga->gdcreg[0x33] = value; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): - svga->gdcreg[0x34] = value; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): - svga->gdcreg[0x35] = value; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): - svga->gdcreg[0x38] = value; - break; - case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): - svga->gdcreg[0x39] = value; - break; - } -} - -void cirrus_write(uint32_t addr, uint8_t val, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - -// pclog("gd5429_write : %05X %02X ", addr, val); - if (clgd->src_ptr != clgd->src_ptr_end) - { - /* bitblt */ - *clgd->src_ptr++ = (uint8_t) val; - if (clgd->src_ptr >= clgd->src_ptr_end) - { - cirrus_bitblt_cputovideo_next(clgd, svga); - } - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + clgd->bank[(addr >> 15) & 1]; -// pclog("%08X\n", addr); -// svga_write_linear(addr, val, &clgd->svga); - svga->writemode = svga->gdcreg[0x05] & 0x7; - if (svga->writemode < 4 || svga->writemode > 5 || ((svga->gdcreg[0x0B] & 0x4) == 0)) { - svga_write_linear(addr, val, &clgd->svga); - } else { - if ((svga->gdcreg[0x0B] & 0x14) != 0x14) { - svga_write_mode45_8bpp(clgd, svga->writemode, - addr, - val); - } else { - svga_write_mode45_16bpp(clgd, svga->writemode, - addr, - val); - } - } -} - -uint8_t cirrus_read(uint32_t addr, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - svga_t *svga = &clgd->svga; - uint8_t ret; - -// pclog("gd5429_read : %05X ", addr); - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + clgd->bank[(addr >> 15) & 1]; - ret = svga_read_linear(addr, &clgd->svga); -// pclog("%08X %02X\n", addr, ret); - return ret; -} - - -static void *clgd_init(device_t *info) -{ - clgd = malloc(sizeof(clgd_t)); - svga_t *svga = &clgd->svga; - wchar_t *romfn = NULL; - int id = info->local; - - memset(clgd, 0x00, sizeof(clgd_t)); - - switch(id) { - case CIRRUS_ID_CLGD5422: - romfn = BIOS_GD5422_PATH; - break; - - case CIRRUS_ID_CLGD5429: - romfn = BIOS_GD5429_PATH; - break; - - case CIRRUS_ID_CLGD5430: - romfn = BIOS_GD5430_PATH; - break; - - case CIRRUS_ID_CLGD5430VL: - romfn = BIOS_GD5430VL_PATH; - id = CIRRUS_ID_CLGD5430; - break; - - case CIRRUS_ID_CLGD5434: - romfn = BIOS_GD5434_PATH; - break; - - case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; - break; - - case CIRRUS_ID_CLGD5440: - romfn = BIOS_GD5440_PATH; - break; - - case CIRRUS_ID_CLGD5446: - romfn = BIOS_GD5446_PATH; - break; - - case CIRRUS_ID_CLGD6235: - romfn = BIOS_GD6235_PATH; - break; - } - - rom_init(&clgd->bios_rom, romfn, - 0xc0000, 0x8000, 0x7fff, - 0, MEM_MAPPING_EXTERNAL); - - svga_init(&clgd->svga, clgd, 1 << 21, /*2mb*/ - clgd_recalctimings, - clgd_in, clgd_out, - clgd_hwcursor_draw, - NULL); - - mem_mapping_set_handler(&svga->mapping, - cirrus_read, NULL, NULL, - cirrus_write, NULL, NULL); - mem_mapping_set_p(&svga->mapping, clgd); - - mem_mapping_add(&clgd->mmio_mapping, 0, 0, - cirrus_mmio_blt_read, NULL, NULL, - cirrus_mmio_blt_write, NULL, NULL, NULL, 0, clgd); - - io_sethandler(0x03c0, 32, - clgd_in, NULL, NULL, - clgd_out, NULL, NULL, clgd); - - if (id < CIRRUS_ID_CLGD5428) { - /* 1 MB */ - clgd->vram_size = (1 << 20); - clgd->vram_code = 2; - - svga->seqregs[0xf] = 0x18; - svga->seqregs[0x1f] = 0x22; - } else if ((id >= CIRRUS_ID_CLGD5428) && (id <= CIRRUS_ID_CLGD5430)) { - /* 2 MB */ - clgd->vram_size = (1 << 21); - clgd->vram_code = 3; - - svga->seqregs[0xf] = 0x18; - svga->seqregs[0x1f] = 0x22; - } else if (id >= CIRRUS_ID_CLGD5434) { - /* 4 MB */ - clgd->vram_size = (1 << 22); - clgd->vram_code = 4; - - svga->seqregs[0xf] = 0x98; - svga->seqregs[0x1f] = 0x2d; - svga->seqregs[0x17] = 0x20; - svga->gdcreg[0x18] = 0xf; - } - - // Seems the 5436 and 5446 BIOS'es never turn on that bit until it's actually needed, - // therefore they also don't turn it back off on 640x480x4bpp, - // therefore, we need to make sure the VRAM mask is correct at start. - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? (clgd->vram_size - 1) : 0x3ffff; - clgd->linear_mmio_mask = (svga->crtc[0x1b] & 2) ? (clgd->vram_size - 256) : (0x40000 - 256); - - svga->seqregs[0x15] = clgd->vram_code; - if ((id >= CIRRUS_ID_CLGD5422) && (id <= CIRRUS_ID_CLGD5429)) - svga->seqregs[0xa] = (clgd->vram_code << 3); - - svga->crtc[0x27] = id; - - // clgd_recalc_mapping(clgd); - /* force refresh */ - // cirrus_update_bank_ptr(s, 0); - // cirrus_update_bank_ptr(s, 1); - - init_rops(); - - return clgd; -} - - -static void clgd_close(void *p) -{ - clgd_t *clgd = (clgd_t *)p; - - svga_close(&clgd->svga); - - free(clgd); -} - - -static void clgd_speed_changed(void *p) -{ - clgd_t *clgd = (clgd_t *)p; - - svga_recalctimings(&clgd->svga); -} - - -static void clgd_force_redraw(void *p) -{ - clgd_t *clgd = (clgd_t *)p; - - clgd->svga.fullchange = changeframecount; -} - - -static void clgd_add_status_info(char *s, int max_len, void *p) -{ - clgd_t *clgd = (clgd_t *)p; - - svga_add_status_info(s, max_len, &clgd->svga); -} - - -static int gd5422_available(void) -{ - return rom_present(BIOS_GD5422_PATH); -} - - -static int gd5429_available(void) -{ - return rom_present(BIOS_GD5429_PATH); -} - - -static int gd5430_available(void) -{ - return rom_present(BIOS_GD5430_PATH); -} - - -static int dia5430_available(void) -{ - return rom_present(BIOS_GD5430VL_PATH); -} - - -static int gd5434_available(void) -{ - return rom_present(BIOS_GD5434_PATH); -} - - -static int gd5436_available(void) -{ - return rom_present(BIOS_GD5436_PATH); -} - - -static int gd5440_available(void) -{ - return rom_present(BIOS_GD5440_PATH); -} - - -static int gd5446_available(void) -{ - return rom_present(BIOS_GD5446_PATH); -} - - -static int gd6235_available(void) -{ - return rom_present(BIOS_GD6235_PATH); -} - - -device_t gd5422_device = -{ - "Cirrus Logic GD5422", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5422, - clgd_init, clgd_close, NULL, - gd5422_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5429_device = -{ - "Cirrus Logic GD5429", - DEVICE_VLB | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5429, - clgd_init, clgd_close, NULL, - gd5429_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5430_device = -{ - "Cirrus Logic GD5430", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5430, - clgd_init, clgd_close, NULL, - gd5430_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t dia5430_device = -{ - "Diamond CL-GD5430 VLB", - DEVICE_VLB | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5430VL, - clgd_init, clgd_close, NULL, - dia5430_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5434_device = -{ - "Cirrus Logic GD5434", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5434, - clgd_init, clgd_close, NULL, - gd5434_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5436_device = -{ - "Cirrus Logic GD5436", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5436, - clgd_init, clgd_close, NULL, - gd5436_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5440_device = -{ - "Cirrus Logic GD5440", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5440, - clgd_init, clgd_close, NULL, - gd5440_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd5446_device = -{ - "Cirrus Logic GD5446", - DEVICE_VLB | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD5446, - clgd_init, clgd_close, NULL, - gd5446_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; - -device_t gd6235_device = -{ - "Cirrus Logic GD6235", - DEVICE_ISA | DEVICE_NOT_WORKING, - CIRRUS_ID_CLGD6235, - clgd_init, clgd_close, NULL, - gd6235_available, - clgd_speed_changed, - clgd_force_redraw, - clgd_add_status_info, - NULL -}; diff --git a/src/video/vid_cl_gd.h b/src/video/vid_cl_gd.h deleted file mode 100644 index 12eff1951..000000000 --- a/src/video/vid_cl_gd.h +++ /dev/null @@ -1,220 +0,0 @@ -// ID -#define CIRRUS_ID_CLGD6225 (0x02<<2) -#define CIRRUS_ID_CLGD5402 (0x06<<2) /* Also Acumos AVGA2 */ -#define CIRRUS_ID_CLGD7542 (0x0B<<2) /* Nordic */ -#define CIRRUS_ID_CLGD7543 (0x0C<<2) /* Viking - guess */ -#define CIRRUS_ID_CLGD7541 (0x0D<<2) /* Nordic Lite */ -#define CIRRUS_ID_CLGD6215 (0x12<<2) -#define CIRRUS_ID_CLGD6235 (0x22<<2) /* Also 5402 */ -#define CIRRUS_ID_CLGD5422 (0x23<<2) -#define CIRRUS_ID_CLGD5426 (0x24<<2) -#define CIRRUS_ID_CLGD5424 (0x25<<2) /* Also 5422-80 */ -#define CIRRUS_ID_CLGD5428 (0x26<<2) -#define CIRRUS_ID_CLGD5429 (0x27<<2) -#define CIRRUS_ID_CLGD5430 (0x28<<2) -#define CIRRUS_ID_CLGD5430VL (0x28<<2)+10000 /* gets fixed in code */ -#define CIRRUS_ID_CLGD5432 0xA2 -#define CIRRUS_ID_CLGD5434O (0x29<<2) /* O = obsolete, never used? */ -#define CIRRUS_ID_CLGD5434 (0x2A<<2) -#define CIRRUS_ID_CLGD5436 (0x2B<<2) -#define CIRRUS_ID_CLGD5436U (0x3A<<2) -#define CIRRUS_ID_CLGD5440 (0x2C<<2) -#define CIRRUS_ID_CLGD5442 (0x2D<<2) -#define CIRRUS_ID_CLGD5446 (0x2E<<2) -#define CIRRUS_ID_CLGD5455 (0x2F<<2) /* Laguna 3D */ -#define CIRRUS_ID_CLGD6205 (0x32<<2) /* Laguna 3D */ -#define CIRRUS_ID_CLGD5462 (0x34<<2) /* Laguna */ -#define CIRRUS_ID_CLGD5464 (0xD5) /* Laguna BD */ -#define CIRRUS_ID_CLGD5465 (0xD6) /* Laguna 3D */ - -// sequencer 0x07 -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 - -// sequencer 0x0f -#define CIRRUS_MEMSIZE_512k 0x08 -#define CIRRUS_MEMSIZE_1M 0x10 -#define CIRRUS_MEMSIZE_2M 0x18 -#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled. - -// sequencer 0x12 -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear - -// sequencer 0x17 -#define CIRRUS_BUSTYPE_VLBFAST 0x10 -#define CIRRUS_BUSTYPE_PCI 0x20 -#define CIRRUS_BUSTYPE_VLBSLOW 0x30 -#define CIRRUS_BUSTYPE_ISA 0x38 -#define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. -#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 - -// control 0x0b -#define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k - -// control 0x30 -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - -// control 0x31 -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 -#define CIRRUS_BLT_FIFOUSED 0x10 -#define CIRRUS_BLT_AUTOSTART 0x80 - -// control 0x32 -#define CIRRUS_ROP_0 0x00 -#define CIRRUS_ROP_SRC_AND_DST 0x05 -#define CIRRUS_ROP_NOP 0x06 -#define CIRRUS_ROP_SRC_AND_NOTDST 0x09 -#define CIRRUS_ROP_NOTDST 0x0b -#define CIRRUS_ROP_SRC 0x0d -#define CIRRUS_ROP_1 0x0e -#define CIRRUS_ROP_NOTSRC_AND_DST 0x50 -#define CIRRUS_ROP_SRC_XOR_DST 0x59 -#define CIRRUS_ROP_SRC_OR_DST 0x6d -#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90 -#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95 -#define CIRRUS_ROP_SRC_OR_NOTDST 0xad -#define CIRRUS_ROP_NOTSRC 0xd0 -#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 -#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda - -#define CIRRUS_ROP_NOP_INDEX 2 -#define CIRRUS_ROP_SRC_INDEX 5 - -// control 0x33 -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 -#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 -#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 - -// memory-mapped IO -#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword -#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword -#define CIRRUS_MMIO_BLTWIDTH 0x08 // word -#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word -#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word -#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word -#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword -#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword -#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte -#define CIRRUS_MMIO_BLTMODE 0x18 // byte -#define CIRRUS_MMIO_BLTROP 0x1a // byte -#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte -#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word? -#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word? -#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word -#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word -#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word -#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte -#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word -#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word -#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word -#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word -#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte -#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte -#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte - -#define CIRRUS_PNPMMIO_SIZE 0x1000 - -#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */ - -typedef struct clgd_t -{ - mem_mapping_t mmio_mapping; - - svga_t svga; - cl_ramdac_t ramdac; - - rom_t bios_rom; - - PALETTE hiddenpal; - - uint32_t vram_size; - uint8_t vram_code; - - uint32_t linear_mmio_mask; - - uint32_t bank[2]; - uint32_t limit[2]; - - uint32_t ramptr; - int src_counter; - uint8_t *src_ptr; - uint8_t *src_ptr_end; - - struct - { - uint8_t bpp; - uint32_t bg_col, fg_col; - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - int32_t dst_addr, src_addr; - uint8_t mask, mode, rop, modeext; - uint32_t blttc, blttcmask; - uint16_t ld_start_x, ld_start_y, ld_end_x, ld_end_y; - uint8_t ld_ls_inc, ld_ls_ro, ld_ls_mask, ld_ls_ac; - uint16_t bres_k1, bres_k3, bres_err, bres_dm; - uint8_t bres_dir, ld_mode, blt_status; - - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - int x_count; - uint8_t buf[CIRRUS_BLTBUFSIZE]; - - uint16_t pixel_width, pixel_height; - } blt; -} clgd_t; - -typedef void (*cirrus_bitblt_rop_t) (clgd_t *clgd, svga_t *svga, - uint8_t * dst, const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight); - -typedef void (*cirrus_fill_t)(clgd_t *clgd, svga_t *svga, - uint8_t *dst, int dst_pitch, int width, int height); - -cirrus_bitblt_rop_t cirrus_rop; - -extern device_t gd5422_device; -extern device_t gd5429_device; -extern device_t gd5430_device; -extern device_t dia5430_device; -extern device_t gd5434_device; -extern device_t gd5436_device; -extern device_t gd5440_device; -extern device_t gd5446_device; -extern device_t gd6235_device; - -clgd_t *clgd; - -void clgd_recalctimings(svga_t *svga); - -void cirrus_update_memory_access(clgd_t *clgd); - -void cirrus_write(uint32_t addr, uint8_t val, void *p); -uint8_t cirrus_read(uint32_t addr, void *p); diff --git a/src/video/vid_cl_gd_blit.c b/src/video/vid_cl_gd_blit.c deleted file mode 100644 index 5d6ed70a0..000000000 --- a/src/video/vid_cl_gd_blit.c +++ /dev/null @@ -1,847 +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. - * - * This is the CL-GD 5446 blitter, directly from QEMU. - * - * Version: @(#)vid_cl_gd_blit.c 1.0.2 2017/11/04 - * - * Author: Miran Grca, - * - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl_ramdac.h" -#include "vid_cl_gd.h" -#include "vid_cl_gd_blit.h" - - -// Same for all the svga->vrammask which are -s>cirrus_addr_mask in the original. - -// Eventually this needs to be configurable -#define clgd_vram_size clgd->vram_size - -#define true 1 -#define false 0 -#define bool int - -#define glue(a,b) glue_hidden(a,b) -#define glue_hidden(a,b) a ## b - -static uint8_t rop_to_index[256]; - -int cl_gd_ABS(int sval) -{ - if (sval < 0) - { - return -sval; - } - else - { - return sval; - } -} - -bool blit_region_is_unsafe(clgd_t *clgd, svga_t *svga, int32_t pitch, int32_t addr) -{ - if (pitch < 0) - { - int64_t min = addr + ((int64_t)clgd->blt.height-1) * pitch; - int32_t max = addr + clgd->blt.width; - if (min < 0 || max >= clgd_vram_size) return true; - } - else - { - int64_t max = addr + ((int64_t)clgd->blt.height-1) * pitch + clgd->blt.width; - if (max >= clgd_vram_size) return true; - } - return false; -} - -bool blit_is_unsafe(clgd_t *clgd, svga_t *svga) -{ - if (clgd->blt.width > 0) fatal("CL-clgd: Blit width is 0!\n"); - if (clgd->blt.height > 0) fatal("CL-clgd: Blit height is 0!\n"); - - if (clgd->blt.width > CIRRUS_BLTBUFSIZE) return true; - - if (blit_region_is_unsafe(clgd, svga, clgd->blt.dst_pitch, clgd->blt.dst_addr & svga->vram_display_mask)) return true; - if (blit_region_is_unsafe(clgd, svga, clgd->blt.src_pitch, clgd->blt.src_addr & svga->vram_display_mask)) return true; - - return false; -} - -void cirrus_bitblt_rop_nop(clgd_t *clgd, svga_t *svga, uint8_t *dst, const uint8_t *src, int dstpitch, int srcpitch, int bltwidth, int bltheight) -{ -} - -void cirrus_bitblt_fill_nop(clgd_t *clgd, svga_t *svga, uint8_t *dst, int dstpitch, int bltwidth, int bltheight) -{ -} - -#define ROP_NAME 0 -#define ROP_FN(d, s) 0 -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_and_dst -#define ROP_FN(d, s) (s) & (d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_and_notdst -#define ROP_FN(d, s) (s) & (~(d)) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notdst -#define ROP_FN(d, s) ~(d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src -#define ROP_FN(d, s) s -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME 1 -#define ROP_FN(d, s) ~0 -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notsrc_and_dst -#define ROP_FN(d, s) (~(s)) & (d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_xor_dst -#define ROP_FN(d, s) (s) ^ (d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_or_dst -#define ROP_FN(d, s) (s) | (d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notsrc_or_notdst -#define ROP_FN(d, s) (~(s)) | (~(d)) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_notxor_dst -#define ROP_FN(d, s) ~((s) ^ (d)) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME src_or_notdst -#define ROP_FN(d, s) (s) | (~(d)) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notsrc -#define ROP_FN(d, s) (~(s)) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notsrc_or_dst -#define ROP_FN(d, s) (~(s)) | (d) -#include "vid_cl_gd_vga_rop.h" - -#define ROP_NAME notsrc_and_notdst -#define ROP_FN(d, s) (~(s)) & (~(d)) -#include "vid_cl_gd_vga_rop.h" - -const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = { - cirrus_bitblt_rop_fwd_0, - cirrus_bitblt_rop_fwd_src_and_dst, - cirrus_bitblt_rop_nop, - cirrus_bitblt_rop_fwd_src_and_notdst, - cirrus_bitblt_rop_fwd_notdst, - cirrus_bitblt_rop_fwd_src, - cirrus_bitblt_rop_fwd_1, - cirrus_bitblt_rop_fwd_notsrc_and_dst, - cirrus_bitblt_rop_fwd_src_xor_dst, - cirrus_bitblt_rop_fwd_src_or_dst, - cirrus_bitblt_rop_fwd_notsrc_or_notdst, - cirrus_bitblt_rop_fwd_src_notxor_dst, - cirrus_bitblt_rop_fwd_src_or_notdst, - cirrus_bitblt_rop_fwd_notsrc, - cirrus_bitblt_rop_fwd_notsrc_or_dst, - cirrus_bitblt_rop_fwd_notsrc_and_notdst, -}; - -const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { - cirrus_bitblt_rop_bkwd_0, - cirrus_bitblt_rop_bkwd_src_and_dst, - cirrus_bitblt_rop_nop, - cirrus_bitblt_rop_bkwd_src_and_notdst, - cirrus_bitblt_rop_bkwd_notdst, - cirrus_bitblt_rop_bkwd_src, - cirrus_bitblt_rop_bkwd_1, - cirrus_bitblt_rop_bkwd_notsrc_and_dst, - cirrus_bitblt_rop_bkwd_src_xor_dst, - cirrus_bitblt_rop_bkwd_src_or_dst, - cirrus_bitblt_rop_bkwd_notsrc_or_notdst, - cirrus_bitblt_rop_bkwd_src_notxor_dst, - cirrus_bitblt_rop_bkwd_src_or_notdst, - cirrus_bitblt_rop_bkwd_notsrc, - cirrus_bitblt_rop_bkwd_notsrc_or_dst, - cirrus_bitblt_rop_bkwd_notsrc_and_notdst, -}; - -#define TRANSP_ROP(name) {\ - name ## _8,\ - name ## _16,\ - } -#define TRANSP_NOP(func) {\ - func,\ - func,\ - } - -const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = { - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst), - TRANSP_NOP(cirrus_bitblt_rop_nop), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst), - TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst), -}; - -const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = { - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst), - TRANSP_NOP(cirrus_bitblt_rop_nop), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst), - TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst), -}; - -#define ROP2(name) {\ - name ## _8,\ - name ## _16,\ - name ## _24,\ - name ## _32,\ - } - -#define ROP_NOP2(func) {\ - func,\ - func,\ - func,\ - func,\ - } - -const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = { - ROP2(cirrus_patternfill_0), - ROP2(cirrus_patternfill_src_and_dst), - ROP_NOP2(cirrus_bitblt_rop_nop), - ROP2(cirrus_patternfill_src_and_notdst), - ROP2(cirrus_patternfill_notdst), - ROP2(cirrus_patternfill_src), - ROP2(cirrus_patternfill_1), - ROP2(cirrus_patternfill_notsrc_and_dst), - ROP2(cirrus_patternfill_src_xor_dst), - ROP2(cirrus_patternfill_src_or_dst), - ROP2(cirrus_patternfill_notsrc_or_notdst), - ROP2(cirrus_patternfill_src_notxor_dst), - ROP2(cirrus_patternfill_src_or_notdst), - ROP2(cirrus_patternfill_notsrc), - ROP2(cirrus_patternfill_notsrc_or_dst), - ROP2(cirrus_patternfill_notsrc_and_notdst), -}; - -const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { - ROP2(cirrus_colorexpand_transp_0), - ROP2(cirrus_colorexpand_transp_src_and_dst), - ROP_NOP2(cirrus_bitblt_rop_nop), - ROP2(cirrus_colorexpand_transp_src_and_notdst), - ROP2(cirrus_colorexpand_transp_notdst), - ROP2(cirrus_colorexpand_transp_src), - ROP2(cirrus_colorexpand_transp_1), - ROP2(cirrus_colorexpand_transp_notsrc_and_dst), - ROP2(cirrus_colorexpand_transp_src_xor_dst), - ROP2(cirrus_colorexpand_transp_src_or_dst), - ROP2(cirrus_colorexpand_transp_notsrc_or_notdst), - ROP2(cirrus_colorexpand_transp_src_notxor_dst), - ROP2(cirrus_colorexpand_transp_src_or_notdst), - ROP2(cirrus_colorexpand_transp_notsrc), - ROP2(cirrus_colorexpand_transp_notsrc_or_dst), - ROP2(cirrus_colorexpand_transp_notsrc_and_notdst), -}; - -const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { - ROP2(cirrus_colorexpand_0), - ROP2(cirrus_colorexpand_src_and_dst), - ROP_NOP2(cirrus_bitblt_rop_nop), - ROP2(cirrus_colorexpand_src_and_notdst), - ROP2(cirrus_colorexpand_notdst), - ROP2(cirrus_colorexpand_src), - ROP2(cirrus_colorexpand_1), - ROP2(cirrus_colorexpand_notsrc_and_dst), - ROP2(cirrus_colorexpand_src_xor_dst), - ROP2(cirrus_colorexpand_src_or_dst), - ROP2(cirrus_colorexpand_notsrc_or_notdst), - ROP2(cirrus_colorexpand_src_notxor_dst), - ROP2(cirrus_colorexpand_src_or_notdst), - ROP2(cirrus_colorexpand_notsrc), - ROP2(cirrus_colorexpand_notsrc_or_dst), - ROP2(cirrus_colorexpand_notsrc_and_notdst), -}; - -const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = { - ROP2(cirrus_colorexpand_pattern_transp_0), - ROP2(cirrus_colorexpand_pattern_transp_src_and_dst), - ROP_NOP2(cirrus_bitblt_rop_nop), - ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst), - ROP2(cirrus_colorexpand_pattern_transp_notdst), - ROP2(cirrus_colorexpand_pattern_transp_src), - ROP2(cirrus_colorexpand_pattern_transp_1), - ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst), - ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst), - ROP2(cirrus_colorexpand_pattern_transp_src_or_dst), - ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst), - ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst), - ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst), - ROP2(cirrus_colorexpand_pattern_transp_notsrc), - ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst), - ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst), -}; - -const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = { - ROP2(cirrus_colorexpand_pattern_0), - ROP2(cirrus_colorexpand_pattern_src_and_dst), - ROP_NOP2(cirrus_bitblt_rop_nop), - ROP2(cirrus_colorexpand_pattern_src_and_notdst), - ROP2(cirrus_colorexpand_pattern_notdst), - ROP2(cirrus_colorexpand_pattern_src), - ROP2(cirrus_colorexpand_pattern_1), - ROP2(cirrus_colorexpand_pattern_notsrc_and_dst), - ROP2(cirrus_colorexpand_pattern_src_xor_dst), - ROP2(cirrus_colorexpand_pattern_src_or_dst), - ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst), - ROP2(cirrus_colorexpand_pattern_src_notxor_dst), - ROP2(cirrus_colorexpand_pattern_src_or_notdst), - ROP2(cirrus_colorexpand_pattern_notsrc), - ROP2(cirrus_colorexpand_pattern_notsrc_or_dst), - ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst), -}; - -const cirrus_fill_t cirrus_fill[16][4] = { - ROP2(cirrus_fill_0), - ROP2(cirrus_fill_src_and_dst), - ROP_NOP2(cirrus_bitblt_fill_nop), - ROP2(cirrus_fill_src_and_notdst), - ROP2(cirrus_fill_notdst), - ROP2(cirrus_fill_src), - ROP2(cirrus_fill_1), - ROP2(cirrus_fill_notsrc_and_dst), - ROP2(cirrus_fill_src_xor_dst), - ROP2(cirrus_fill_src_or_dst), - ROP2(cirrus_fill_notsrc_or_notdst), - ROP2(cirrus_fill_src_notxor_dst), - ROP2(cirrus_fill_src_or_notdst), - ROP2(cirrus_fill_notsrc), - ROP2(cirrus_fill_notsrc_or_dst), - ROP2(cirrus_fill_notsrc_and_notdst), -}; - -inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) -{ - unsigned int color; - switch (clgd->blt.pixel_width) - { - case 1: - clgd->blt.fg_col = (clgd->blt.fg_col & 0xffffff00); - break; - case 2: - color = (clgd->blt.fg_col & 0xffff00ff) | (svga->gdcreg[0x11] << 8); - clgd->blt.fg_col = le16_to_cpu(color); - break; - case 3: - clgd->blt.fg_col = (clgd->blt.fg_col & 0xff00ffff) | (svga->gdcreg[0x11] << 8) | (svga->gdcreg[0x13] << 16); - break; - default: - case 4: - color = (clgd->blt.fg_col & 0x00ffffff) | (svga->gdcreg[0x11] << 8) | (svga->gdcreg[0x13] << 16) | (svga->gdcreg[0x15] << 24); - clgd->blt.fg_col = le32_to_cpu(color); - break; - } -} - -inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) -{ - unsigned int color; - switch (clgd->blt.pixel_width) - { - case 1: - clgd->blt.bg_col = (clgd->blt.bg_col & 0xffffff00); - break; - case 2: - color = (clgd->blt.bg_col & 0xffff00ff) | (svga->gdcreg[0x10] << 8); - clgd->blt.bg_col = le16_to_cpu(color); - break; - case 3: - clgd->blt.bg_col = (clgd->blt.bg_col & 0xff00ffff) | (svga->gdcreg[0x10] << 8) | (svga->gdcreg[0x12] << 16); - break; - default: - case 4: - color = (clgd->blt.bg_col & 0x00ffffff) | (svga->gdcreg[0x10] << 8) | (svga->gdcreg[0x12] << 16) | (svga->gdcreg[0x14] << 24); - clgd->blt.bg_col = le32_to_cpu(color); - break; - } -} - -void cirrus_invalidate_region(clgd_t *clgd, svga_t *svga, int off_begin, int off_pitch, int bytesperline, int lines) -{ - int x, y; - int off_cur; - int off_cur_end; - - for (y = 0; y < lines; y++) - { - off_cur = off_begin; - off_cur_end = ((off_cur + bytesperline) & svga->vram_display_mask); - // Memory region set dirty - off_begin += off_pitch; - for (x = (off_cur >> 12); x <= (off_cur_end >> 12); x++) - { - svga->changedvram[x]++; - } - } -} - -int cirrus_bitblt_common_patterncopy(clgd_t *clgd, svga_t *svga, const uint8_t * src) -{ - uint8_t *dst; - - dst = svga->vram + (clgd->blt.dst_addr & svga->vram_display_mask); - - if (blit_is_unsafe(clgd, svga)) return 0; - - (*cirrus_rop) (clgd, svga, dst, src, clgd->blt.dst_pitch, 0, clgd->blt.width, clgd->blt.height); - cirrus_invalidate_region(clgd, svga, clgd->blt.dst_addr, clgd->blt.dst_pitch, clgd->blt.width, clgd->blt.height); - - return 1; -} - -/* fill */ - -int cirrus_bitblt_solidfill(clgd_t *clgd, svga_t *svga, int blt_rop) -{ - cirrus_fill_t rop_func; - - if (blit_is_unsafe(clgd, svga)) return 0; - - rop_func = cirrus_fill[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - rop_func(clgd, svga, svga->vram + (clgd->blt.dst_addr & svga->vram_display_mask), clgd->blt.dst_pitch, clgd->blt.width, clgd->blt.height); - cirrus_invalidate_region(clgd, svga, clgd->blt.dst_addr, clgd->blt.dst_pitch, clgd->blt.width, clgd->blt.height); - cirrus_bitblt_reset(clgd, svga); - - return 1; -} - -int cirrus_bitblt_videotovideo_patterncopy(clgd_t *clgd, svga_t *svga) -{ - return cirrus_bitblt_common_patterncopy(clgd, svga, svga->vram + ((clgd->blt.src_addr & ~7) & svga->vram_display_mask)); -} - -void cirrus_do_copy(clgd_t *clgd, svga_t *svga, int dst, int src, int w, int h) -{ - int sx = 0, sy = 0; - int dx = 0, dy = 0; - int notify = 0; - - /* make sure to only copy if it's a plain copy ROP */ - if (*cirrus_rop == cirrus_bitblt_rop_fwd_src || - *cirrus_rop == cirrus_bitblt_rop_bkwd_src) - { - int width, height; - - clgd_recalctimings(svga); - width = svga->video_res_x; - height = svga->video_res_y; - - /* extra x, y */ - sx = (src % cl_gd_ABS(clgd->blt.src_pitch)) / svga->bpp; - sy = (src / cl_gd_ABS(clgd->blt.src_pitch)); - dx = (dst % cl_gd_ABS(clgd->blt.dst_pitch)) / svga->bpp; - dy = (dst / cl_gd_ABS(clgd->blt.dst_pitch)); - - /* normalize width */ - w /= svga->bpp; - - /* if we're doing a backward copy, we have to adjust - our x/y to be the upper left corner (instead of the lower right corner) */ - if (clgd->blt.dst_pitch < 0) - { - sx -= (clgd->blt.width / svga->bpp) - 1; - dx -= (clgd->blt.width / svga->bpp) - 1; - sy -= clgd->blt.height - 1; - dy -= clgd->blt.height - 1; - } - - /* are we in the visible portion of memory? */ - if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && - (sx + w) <= width && (sy + h) <= height && - (dx + w) <= width && (dy + h) <= height) - { - notify = 1; - } - } - - /* we have to flush all prending changes so that the copy - is generated at the appropriate moment in time */ - if (notify) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - - /* we don't have to notify the display that this portion has - changed since qemu_console_copy implies this */ - - cirrus_invalidate_region(clgd, svga, clgd->blt.dst_addr, clgd->blt.dst_pitch, clgd->blt.width, clgd->blt.height); -} - -int cirrus_bitblt_videotovideo_copy(clgd_t *clgd, svga_t *svga) -{ - if (blit_is_unsafe(clgd, svga)) return 0; - - cirrus_do_copy(clgd, svga, clgd->blt.dst_addr - svga->firstline, clgd->blt.src_addr - svga->firstline, - clgd->blt.width, clgd->blt.height); - - return 1; -} - -void cirrus_bitblt_cputovideo_next(clgd_t *clgd, svga_t *svga) -{ - int copy_count; - uint8_t *end_ptr; - - if (clgd->src_counter > 0) - { - if (clgd->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) - { - cirrus_bitblt_common_patterncopy(clgd, svga, clgd->blt.buf); - the_end: - clgd->src_counter = 0; - cirrus_bitblt_reset(clgd, svga); - } - else - { - /* at least one scan line */ - do - { - (*cirrus_rop)(clgd, svga, svga->vram + (clgd->blt.dst_addr & svga->vram_display_mask), clgd->blt.buf, 0, 0, clgd->blt.width, 1); - cirrus_invalidate_region(clgd, svga, clgd->blt.dst_addr, 0 , clgd->blt.width, 1); - clgd->blt.dst_addr += clgd->blt.dst_pitch; - clgd->src_counter -= clgd->blt.src_pitch; - if (clgd->src_counter <= 0) goto the_end; - /* more bytes than needed can be transferred because of - word alignment, so we keep them for the next line */ - /* XXX: keep alignment to speed up transfer */ - end_ptr = clgd->blt.buf + clgd->blt.src_pitch; - copy_count = clgd->src_ptr_end - end_ptr; - memmove(clgd->blt.buf, end_ptr, copy_count); - clgd->src_ptr = clgd->blt.buf + copy_count; - clgd->src_ptr_end = clgd->blt.buf + clgd->blt.src_pitch; - } - while (clgd->src_ptr >= clgd->src_ptr_end); - } - } -} - -void cirrus_bitblt_reset(clgd_t *clgd, svga_t *svga) -{ - int need_update; - - svga->gdcreg[0x31] &= ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); - need_update = clgd->src_ptr != &clgd->blt.buf[0] - || clgd->src_ptr_end != &clgd->blt.buf[0]; - clgd->src_ptr = &clgd->blt.buf[0]; - clgd->src_ptr_end = &clgd->blt.buf[0]; - clgd->src_counter = 0; - if (!need_update) - return; - mem_mapping_set_handler(&clgd->svga.mapping, cirrus_read, NULL, NULL, cirrus_write, NULL, NULL); - mem_mapping_set_p(&clgd->svga.mapping, clgd); - cirrus_update_memory_access(clgd); -} - -int cirrus_bitblt_cputovideo(clgd_t *clgd, svga_t *svga) -{ - int w; - - clgd->blt.mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; - clgd->src_ptr = &clgd->blt.buf[0]; - clgd->src_ptr_end = &clgd->blt.buf[0]; - - if (clgd->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) - { - if (clgd->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - { - clgd->blt.src_pitch = 8; - } - else - { - /* XXX: check for 24 bpp */ - clgd->blt.src_pitch = 8 * 8 * clgd->blt.pixel_width; - } - clgd->src_counter = clgd->blt.src_pitch; - } - else - { - if (clgd->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - { - w = clgd->blt.width / clgd->blt.pixel_width; - if (clgd->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) - clgd->blt.src_pitch = ((w + 31) >> 5); - else - clgd->blt.src_pitch = ((w + 7) >> 3); - } - else - { - /* always align input size to 32 bit */ - clgd->blt.src_pitch = (clgd->blt.width + 3) & ~3; - } - clgd->src_counter = clgd->blt.src_pitch * clgd->blt.height; - } - clgd->src_ptr = clgd->blt.buf; - clgd->src_ptr_end = clgd->blt.buf + clgd->blt.src_pitch; - cirrus_update_memory_access(clgd); - return 1; -} - -int cirrus_bitblt_videotocpu(clgd_t *clgd, svga_t *svga) -{ - /* XXX */ -#ifdef DEBUG_BITBLT - printf("cirrus: bitblt (video to cpu) is not implemented yet\n"); -#endif - return 0; -} - -int cirrus_bitblt_videotovideo(clgd_t *clgd, svga_t *svga) -{ - int ret; - - if (clgd->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) - { - ret = cirrus_bitblt_videotovideo_patterncopy(clgd, svga); - } - else - { - ret = cirrus_bitblt_videotovideo_copy(clgd, svga); - } - if (ret) - cirrus_bitblt_reset(clgd, svga); - return ret; -} - -void cirrus_bitblt_start(clgd_t *clgd, svga_t *svga) -{ - uint8_t blt_rop; - - svga->gdcreg[0x31] |= CIRRUS_BLT_BUSY; - - clgd->blt.width = (svga->gdcreg[0x20] | (svga->gdcreg[0x21] << 8)) + 1; - clgd->blt.height = (svga->gdcreg[0x22] | (svga->gdcreg[0x23] << 8)) + 1; - clgd->blt.dst_pitch = (svga->gdcreg[0x24] | (svga->gdcreg[0x25] << 8)); - clgd->blt.src_pitch = (svga->gdcreg[0x26] | (svga->gdcreg[0x27] << 8)); - clgd->blt.dst_addr = (svga->gdcreg[0x28] | (svga->gdcreg[0x29] << 8) | (svga->gdcreg[0x2a] << 16)); - clgd->blt.src_addr = (svga->gdcreg[0x2c] | (svga->gdcreg[0x2d] << 8) | (svga->gdcreg[0x2e] << 16)); - clgd->blt.mode = svga->gdcreg[0x30]; - clgd->blt.modeext = svga->gdcreg[0x33]; - blt_rop = svga->gdcreg[0x32]; - - switch (clgd->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { - case CIRRUS_BLTMODE_PIXELWIDTH8: - clgd->blt.pixel_width = 1; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - clgd->blt.pixel_width = 2; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - clgd->blt.pixel_width = 3; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - clgd->blt.pixel_width = 4; - break; - default: - goto bitblt_ignore; - } - clgd->blt.mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK; - - if ((clgd->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) - { - goto bitblt_ignore; - } - - if ((clgd->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) && - (clgd->blt.mode & (CIRRUS_BLTMODE_MEMSYSDEST | CIRRUS_BLTMODE_TRANSPARENTCOMP | CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) == - (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) - { - cirrus_bitblt_fgcol(clgd, svga); - cirrus_bitblt_solidfill(clgd, svga, blt_rop); - } - else - { - if ((clgd->blt.mode & (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_PATTERNCOPY)) == CIRRUS_BLTMODE_COLOREXPAND) - { - if (clgd->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) - { - if (clgd->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) - cirrus_bitblt_bgcol(clgd, svga); - else - cirrus_bitblt_fgcol(clgd, svga); - cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - else - { - cirrus_bitblt_fgcol(clgd, svga); - cirrus_bitblt_bgcol(clgd, svga); - cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - } - else if (clgd->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) - { - if (clgd->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - { - if (clgd->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) - { - if (clgd->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) - cirrus_bitblt_bgcol(clgd, svga); - else - cirrus_bitblt_fgcol(clgd, svga); - cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - else - { - cirrus_bitblt_fgcol(clgd, svga); - cirrus_bitblt_bgcol(clgd, svga); - cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - } - else - { - cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - } - else - { - if (clgd->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) - { - if (clgd->blt.pixel_width > 2) - { - goto bitblt_ignore; - } - if (clgd->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - { - clgd->blt.dst_pitch = -clgd->blt.dst_pitch; - clgd->blt.src_pitch = -clgd->blt.src_pitch; - cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - else - { - cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][clgd->blt.pixel_width - 1]; - } - } - else - { - if (clgd->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - { - clgd->blt.dst_pitch = -clgd->blt.dst_pitch; - clgd->blt.src_pitch = -clgd->blt.src_pitch; - cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; - } - else - { - cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; - } - } - } - // setup bitblt engine. - if (clgd->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - { - if (!cirrus_bitblt_cputovideo(clgd, svga)) goto bitblt_ignore; - } - else if (clgd->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) - { - if (!cirrus_bitblt_videotocpu(clgd, svga)) goto bitblt_ignore; - } - else - { - if (!cirrus_bitblt_videotovideo(clgd, svga)) goto bitblt_ignore; - } - } - return; -bitblt_ignore:; - cirrus_bitblt_reset(clgd, svga); -} - -void cirrus_write_bitblt(clgd_t *clgd, svga_t *svga, uint8_t reg_value) -{ - uint8_t old_value; - - old_value = svga->gdcreg[0x31]; - svga->gdcreg[0x31] = reg_value; - - if (((old_value & CIRRUS_BLT_RESET) != 0) && - ((reg_value & CIRRUS_BLT_RESET) == 0)) - { - cirrus_bitblt_reset(clgd, svga); - } - else if (((old_value & CIRRUS_BLT_START) == 0) && - ((reg_value & CIRRUS_BLT_START) != 0)) - { - cirrus_bitblt_start(clgd, svga); - } -} - -void init_rops() -{ - int i = 0; - - for(i = 0;i < 256; i++) - rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */ - rop_to_index[CIRRUS_ROP_0] = 0; - rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1; - rop_to_index[CIRRUS_ROP_NOP] = 2; - rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3; - rop_to_index[CIRRUS_ROP_NOTDST] = 4; - rop_to_index[CIRRUS_ROP_SRC] = 5; - rop_to_index[CIRRUS_ROP_1] = 6; - rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7; - rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8; - rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9; - rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10; - rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11; - rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12; - rop_to_index[CIRRUS_ROP_NOTSRC] = 13; - rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14; - rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15; -} diff --git a/src/video/vid_cl_gd_blit.h b/src/video/vid_cl_gd_blit.h deleted file mode 100644 index ebf22eb56..000000000 --- a/src/video/vid_cl_gd_blit.h +++ /dev/null @@ -1,8 +0,0 @@ -#define le32_to_cpu(x) (x) -#define le16_to_cpu(x) (x) - -void cirrus_bitblt_cputovideo_next(clgd_t *clgd, svga_t *svga); -void cirrus_bitblt_reset(clgd_t *clgd, svga_t *svga); -void cirrus_bitblt_start(clgd_t *clgd, svga_t *svga); -void cirrus_write_bitblt(clgd_t *clgd, svga_t *svga, uint8_t reg_value); -void init_rops(); \ No newline at end of file diff --git a/src/video/vid_cl_gd_vga_rop.h b/src/video/vid_cl_gd_vga_rop.h deleted file mode 100644 index d03516ba3..000000000 --- a/src/video/vid_cl_gd_vga_rop.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * QEMU Cirrus CLGD 54xx VGA Emulator. - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) -{ - *dst = ROP_FN(*dst, src); -} - -inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) -{ - *dst = ROP_FN(*dst, src); -} - -inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) -{ - *dst = ROP_FN(*dst, src); -} - -#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s) -#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s) -#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s) -#undef ROP_FN - -void -glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - dstpitch -= bltwidth; - srcpitch -= bltwidth; - - if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { - return; - } - - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x++) { - ROP_OP(dst, *src); - dst++; - src++; - } - dst += dstpitch; - src += srcpitch; - } -} - -void -glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - dstpitch += bltwidth; - srcpitch += bltwidth; - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x++) { - ROP_OP(dst, *src); - dst--; - src--; - } - dst += dstpitch; - src += srcpitch; - } -} - -void -glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - uint8_t p; - dstpitch -= bltwidth; - srcpitch -= bltwidth; - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x++) { - p = *dst; - ROP_OP(&p, *src); - if (p != svga->gdcreg[0x34]) *dst = p; - dst++; - src++; - } - dst += dstpitch; - src += srcpitch; - } -} - -void -glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - uint8_t p; - dstpitch += bltwidth; - srcpitch += bltwidth; - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x++) { - p = *dst; - ROP_OP(&p, *src); - if (p != svga->gdcreg[0x34]) *dst = p; - dst--; - src--; - } - dst += dstpitch; - src += srcpitch; - } -} - -void -glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - uint8_t p1, p2; - dstpitch -= bltwidth; - srcpitch -= bltwidth; - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x+=2) { - p1 = *dst; - p2 = *(dst+1); - ROP_OP(&p1, *src); - ROP_OP(&p2, *(src + 1)); - if ((p1 != svga->gdcreg[0x34]) || (p2 != svga->gdcreg[0x35])) { - *dst = p1; - *(dst+1) = p2; - } - dst+=2; - src+=2; - } - dst += dstpitch; - src += srcpitch; - } -} - -void -glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(clgd_t *clgd, svga_t *svga, - uint8_t *dst,const uint8_t *src, - int dstpitch,int srcpitch, - int bltwidth,int bltheight) -{ - int x,y; - uint8_t p1, p2; - dstpitch += bltwidth; - srcpitch += bltwidth; - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x+=2) { - p1 = *(dst-1); - p2 = *dst; - ROP_OP(&p1, *(src - 1)); - ROP_OP(&p2, *src); - if ((p1 != svga->gdcreg[0x34]) || (p2 != svga->gdcreg[0x35])) { - *(dst-1) = p1; - *dst = p2; - } - dst-=2; - src-=2; - } - dst += dstpitch; - src += srcpitch; - } -} - -#define DEPTH 8 -#include "vid_cl_gd_vga_rop2.h" - -#define DEPTH 16 -#include "vid_cl_gd_vga_rop2.h" - -#define DEPTH 24 -#include "vid_cl_gd_vga_rop2.h" - -#define DEPTH 32 -#include "vid_cl_gd_vga_rop2.h" - -#undef ROP_NAME -#undef ROP_OP -#undef ROP_OP_16 -#undef ROP_OP_32 \ No newline at end of file diff --git a/src/video/vid_cl_gd_vga_rop2.h b/src/video/vid_cl_gd_vga_rop2.h deleted file mode 100644 index 787c40744..000000000 --- a/src/video/vid_cl_gd_vga_rop2.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * QEMU Cirrus CLGD 54xx VGA Emulator. - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#if DEPTH == 8 -#define PUTPIXEL() ROP_OP(&d[0], col) -#elif DEPTH == 16 -#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col) -#elif DEPTH == 24 -#define PUTPIXEL() ROP_OP(&d[0], col); \ - ROP_OP(&d[1], (col >> 8)); \ - ROP_OP(&d[2], (col >> 16)) -#elif DEPTH == 32 -#define PUTPIXEL() ROP_OP_32(((uint32_t *)&d[0]), col) -#else -#error unsupported DEPTH -#endif - -void -glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, uint8_t * dst, - const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight) -{ - uint8_t *d; - int x, y, pattern_y, pattern_pitch, pattern_x; - unsigned int col; - const uint8_t *src1; -#if DEPTH == 24 - int skipleft = svga->gdcreg[0x2f] & 0x1f; -#else - int skipleft = (svga->gdcreg[0x2f] & 0x07) * (DEPTH / 8); -#endif - -#if DEPTH == 8 - pattern_pitch = 8; -#elif DEPTH == 16 - pattern_pitch = 16; -#else - pattern_pitch = 32; -#endif - pattern_y = clgd->blt.src_addr & 7; - for(y = 0; y < bltheight; y++) { - pattern_x = skipleft; - d = dst + skipleft; - src1 = src + pattern_y * pattern_pitch; - for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) { -#if DEPTH == 8 - col = src1[pattern_x]; - pattern_x = (pattern_x + 1) & 7; -#elif DEPTH == 16 - col = ((uint16_t *)(src1 + pattern_x))[0]; - pattern_x = (pattern_x + 2) & 15; -#elif DEPTH == 24 - { - const uint8_t *src2 = src1 + pattern_x * 3; - col = src2[0] | (src2[1] << 8) | (src2[2] << 16); - pattern_x = (pattern_x + 1) & 7; - } -#else - col = ((uint32_t *)(src1 + pattern_x))[0]; - pattern_x = (pattern_x + 4) & 31; -#endif - PUTPIXEL(); - d += (DEPTH / 8); - } - pattern_y = (pattern_y + 1) & 7; - dst += dstpitch; - } -} - -/* NOTE: srcpitch is ignored */ -void -glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, uint8_t * dst, - const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight) -{ - uint8_t *d; - int x, y; - unsigned bits, bits_xor; - unsigned int col; - unsigned bitmask; - unsigned index; -#if DEPTH == 24 - int dstskipleft = svga->gdcreg[0x2f] & 0x1f; - int srcskipleft = dstskipleft / 3; -#else - int srcskipleft = svga->gdcreg[0x2f] & 0x07; - int dstskipleft = srcskipleft * (DEPTH / 8); -#endif - - if (clgd->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { - bits_xor = 0xff; - col = clgd->blt.bg_col; - } else { - bits_xor = 0x00; - col = clgd->blt.fg_col; - } - - for(y = 0; y < bltheight; y++) { - bitmask = 0x80 >> srcskipleft; - bits = *src++ ^ bits_xor; - d = dst + dstskipleft; - for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { - if ((bitmask & 0xff) == 0) { - bitmask = 0x80; - bits = *src++ ^ bits_xor; - } - index = (bits & bitmask); - if (index) { - PUTPIXEL(); - } - d += (DEPTH / 8); - bitmask >>= 1; - } - dst += dstpitch; - } -} - -void -glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, uint8_t * dst, - const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight) -{ - uint32_t colors[2]; - uint8_t *d; - int x, y; - unsigned bits; - unsigned int col; - unsigned bitmask; - int srcskipleft = svga->gdcreg[0x2f] & 0x07; - int dstskipleft = srcskipleft * (DEPTH / 8); - - colors[0] = clgd->blt.bg_col; - colors[1] = clgd->blt.fg_col; - for(y = 0; y < bltheight; y++) { - bitmask = 0x80 >> srcskipleft; - bits = *src++; - d = dst + dstskipleft; - for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { - if ((bitmask & 0xff) == 0) { - bitmask = 0x80; - bits = *src++; - } - col = colors[!!(bits & bitmask)]; - PUTPIXEL(); - d += (DEPTH / 8); - bitmask >>= 1; - } - dst += dstpitch; - } -} - -void -glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, uint8_t * dst, - const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight) -{ - uint8_t *d; - int x, y, bitpos, pattern_y; - unsigned int bits, bits_xor; - unsigned int col; -#if DEPTH == 24 - int dstskipleft = svga->gdcreg[0x2f] & 0x1f; - int srcskipleft = dstskipleft / 3; -#else - int srcskipleft = svga->gdcreg[0x2f] & 0x07; - int dstskipleft = srcskipleft * (DEPTH / 8); -#endif - - if (clgd->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { - bits_xor = 0xff; - col = clgd->blt.bg_col; - } else { - bits_xor = 0x00; - col = clgd->blt.fg_col; - } - pattern_y = clgd->blt.src_addr & 7; - - for(y = 0; y < bltheight; y++) { - bits = src[pattern_y] ^ bits_xor; - bitpos = 7 - srcskipleft; - d = dst + dstskipleft; - for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { - if ((bits >> bitpos) & 1) { - PUTPIXEL(); - } - d += (DEPTH / 8); - bitpos = (bitpos - 1) & 7; - } - pattern_y = (pattern_y + 1) & 7; - dst += dstpitch; - } -} - -void -glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, uint8_t * dst, - const uint8_t * src, - int dstpitch, int srcpitch, - int bltwidth, int bltheight) -{ - uint32_t colors[2]; - uint8_t *d; - int x, y, bitpos, pattern_y; - unsigned int bits; - unsigned int col; - int srcskipleft = svga->gdcreg[0x2f] & 0x07; - int dstskipleft = srcskipleft * (DEPTH / 8); - - colors[0] = clgd->blt.bg_col; - colors[1] = clgd->blt.fg_col; - pattern_y = clgd->blt.src_addr & 7; - - for(y = 0; y < bltheight; y++) { - bits = src[pattern_y]; - bitpos = 7 - srcskipleft; - d = dst + dstskipleft; - for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { - col = colors[(bits >> bitpos) & 1]; - PUTPIXEL(); - d += (DEPTH / 8); - bitpos = (bitpos - 1) & 7; - } - pattern_y = (pattern_y + 1) & 7; - dst += dstpitch; - } -} - -void -glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH) - (clgd_t *clgd, svga_t *svga, - uint8_t *dst, int dst_pitch, - int width, int height) -{ - uint8_t *d, *d1; - uint32_t col; - int x, y; - - col = clgd->blt.fg_col; - - d1 = dst; - for(y = 0; y < height; y++) { - d = d1; - for(x = 0; x < width; x += (DEPTH / 8)) { - PUTPIXEL(); - d += (DEPTH / 8); - } - d1 += dst_pitch; - } -} - -#undef DEPTH -#undef PUTPIXEL \ No newline at end of file diff --git a/src/video/vid_cl_ramdac.c b/src/video/vid_cl_ramdac.c deleted file mode 100644 index a371708f6..000000000 --- a/src/video/vid_cl_ramdac.c +++ /dev/null @@ -1,121 +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 Cirrus Logic RAMDAC. - * - * Version: @(#)vid_cl_ramdac.c 1.0.2 2017/11/04 - * - * Author: Miran Grca, - * - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_cl_ramdac.h" -#include "vid_cl_gd.h" -#include "vid_cl_gd_blit.h" - - -void cl_ramdac_out(uint16_t addr, uint8_t val, cl_ramdac_t *ramdac, void *clgd, svga_t *svga) -{ - clgd_t *real_clgd = (clgd_t *) clgd; - //pclog("OUT RAMDAC %04X %02X\n",addr,val); - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - ramdac->ctrl = val; - svga_recalctimings(svga); - return; - } - ramdac->state = 0; - break; - - case 0x3C7: case 0x3C8: - ramdac->state = 0; - break; - - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) - { - ramdac->state = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) - { - case 0: - real_clgd->hiddenpal[svga->dac_write & 0xf].r = val & 63; - svga->dac_pos++; - break; - case 1: - real_clgd->hiddenpal[svga->dac_write & 0xf].g = val & 63; - svga->dac_pos++; - break; - case 2: - real_clgd->hiddenpal[svga->dac_write & 0xf].b = val & 63; - svga->dac_pos = 0; - svga->dac_write = (svga->dac_write + 1) & 255; - break; - } - return; - } - ramdac->state = 0; - break; - } - svga_out(addr, val, svga); -} - -uint8_t cl_ramdac_in(uint16_t addr, cl_ramdac_t *ramdac, void *clgd, svga_t *svga) -{ - clgd_t *real_clgd = (clgd_t *) clgd; - //pclog("IN RAMDAC %04X\n",addr); - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: case 0x3C8: - ramdac->state = 0; - break; - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) - { - ramdac->state = 0; - switch (svga->dac_pos) - { - case 0: - svga->dac_pos++; - return real_clgd->hiddenpal[svga->dac_read & 0xf].r; - case 1: - svga->dac_pos++; - return real_clgd->hiddenpal[svga->dac_read & 0xf].g; - case 2: - svga->dac_pos=0; - svga->dac_read = (svga->dac_read + 1) & 255; - return real_clgd->hiddenpal[(svga->dac_read - 1) & 15].b; - } - } - ramdac->state = 0; - break; - } - return svga_in(addr, svga); -} diff --git a/src/video/vid_cl_ramdac.h b/src/video/vid_cl_ramdac.h deleted file mode 100644 index 459ece144..000000000 --- a/src/video/vid_cl_ramdac.h +++ /dev/null @@ -1,8 +0,0 @@ -typedef struct cl_ramdac_t -{ - int state; - uint8_t ctrl; -} cl_ramdac_t; - -void cl_ramdac_out(uint16_t addr, uint8_t val, cl_ramdac_t *ramdac, void *clgd, svga_t *svga); -uint8_t cl_ramdac_in(uint16_t addr, cl_ramdac_t *ramdac, void *clgd, svga_t *svga); \ No newline at end of file diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 93732eb2e..52142c387 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -8,7 +8,7 @@ * * Define all known video cards. * - * Version: @(#)vid_table.c 1.0.18 2018/02/12 + * Version: @(#)vid_table.c 1.0.19 2018/02/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -35,7 +35,7 @@ #include "vid_ati28800.h" #include "vid_ati_mach64.h" #include "vid_cga.h" -#include "vid_cl5428.h" +#include "vid_cl54xx.h" #include "vid_compaq_cga.h" #include "vid_ega.h" #include "vid_et4000.h" @@ -69,8 +69,8 @@ enum { }; typedef struct { - char name[64]; - char internal_name[24]; + const char *name; + const char *internal_name; device_t *device; int legacy_id; video_timings_t timing; @@ -136,10 +136,11 @@ video_cards[] = { {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, GFX_TGUI9440_PCI, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, GFX_ET4000W32_CARDEX_VLB, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, #if defined(DEV_BRANCH) && defined(USE_STEALTH32) {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif - {"[VLB] Diamond SpeedStar PRO (CL-GD5428)", "cl_gd5428_vlb", &gd5428_device, GFX_CL_GD5428, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"[VLB] Diamond SpeedStar PRO (CL-GD5428)", "cl_gd5428_vlb", &gd5428_device, GFX_CL_GD5428, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb", &s3_virge_vlb_device, GFX_VIRGE_VLB, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device, GFX_STEALTH64_VLB, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, @@ -193,7 +194,7 @@ video_card_available(int card) char * video_card_getname(int card) { - return(video_cards[card].name); + return((char *) video_cards[card].name); } @@ -226,7 +227,7 @@ video_card_getid(char *s) int c = 0; while (video_cards[c].legacy_id != -1) { - if (!strcmp(video_cards[c].name, s)) + if (!strcmp((char *) video_cards[c].name, s)) return(c); c++; } @@ -260,7 +261,7 @@ video_new_to_old(int card) char * video_get_internal_name(int card) { - return(video_cards[card].internal_name); + return((char *) video_cards[card].internal_name); } @@ -270,7 +271,7 @@ video_get_video_from_internal_name(char *s) int c = 0; while (video_cards[c].legacy_id != -1) { - if (!strcmp(video_cards[c].internal_name, s)) + if (!strcmp((char *) video_cards[c].internal_name, s)) return(video_cards[c].legacy_id); c++; } diff --git a/src/video/video.h b/src/video/video.h index 3461bdee5..537090976 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -8,7 +8,7 @@ * * Definitions for the video controller module. * - * Version: @(#)video.h 1.0.16 2018/02/12 + * Version: @(#)video.h 1.0.17 2018/02/18 * * Authors: Sarah Walker, * Miran Grca, @@ -68,7 +68,8 @@ enum { GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */ GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */ GFX_MACH64VT2, /* ATI Mach64 VT2 */ - GFX_CL_GD5428, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD5428) */ + GFX_CL_GD5428, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5428) */ + GFX_CL_GD5429, /* Cirrus Logic CL-GD 5428 */ #if defined(DEV_BRANCH) && defined(USE_RIVA) GFX_RIVATNT, /* nVidia Riva TNT */ GFX_RIVATNT2, /* nVidia Riva TNT2 */ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index f44bf9fe5..17c66994d 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.101 2018/02/11 +# Version: @(#)Makefile.mingw 1.0.102 2018/02/18 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -455,8 +455,7 @@ SNDOBJ := sound.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ - midi.o $(FSYNTHOBJ) $(MUNTOBJ) \ - midi_system.o \ + midi.o midi_system.o \ snd_speaker.o \ snd_pssj.o \ snd_lpt_dac.o snd_lpt_dss.o \ @@ -486,7 +485,7 @@ VIDOBJ := video.o \ vid_ati18800.o vid_ati28800.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_ics2595.o \ - vid_cl5428.o \ + vid_cl54xx.o \ vid_et4000.o vid_sc1502x_ramdac.o \ vid_et4000w32.o vid_stg_ramdac.o \ vid_oti067.o \ @@ -506,7 +505,8 @@ PLATOBJ := win.o \ OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ - $(PLATOBJ) $(UIOBJ) $(DEVBROBJ) + $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) \ + $(DEVBROBJ) ifdef EXOBJ OBJ += $(EXOBJ) endif diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index fc575b360..3224fcde1 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -8,13 +8,13 @@ * * Windows device configuration dialog implementation. * - * Version: @(#)win_devconf.c 1.0.11 2017/12/13 + * Version: @(#)win_devconf.c 1.0.12 2018/02/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -72,7 +72,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) switch (config->type) { case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); SendMessage(h, BM_SETCHECK, val_int, 0); @@ -80,7 +80,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -97,7 +97,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_MIDI: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); num = plat_midi_get_num_devs(); for (c = 0; c < num; c++) @@ -113,7 +113,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_SPINNER: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); _swprintf(ws, L"%i", val_int); SendMessage(h, WM_SETTEXT, 0, (LPARAM)ws); @@ -123,7 +123,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case CONFIG_FNAME: { - wchar_t* str = config_get_wstring(config_device->name, config->name, 0); + wchar_t* str = config_get_wstring((char *) config_device->name, (char *) config->name, 0); if (str) SendMessage(h, WM_SETTEXT, 0, (LPARAM)str); id += 3; @@ -131,7 +131,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_HEX16: - val_int = config_get_hex16(config_device->name, config->name, config->default_int); + val_int = config_get_hex16((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -148,7 +148,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_HEX20: - val_int = config_get_hex20(config_device->name, config->name, config->default_int); + val_int = config_get_hex20((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -189,7 +189,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) switch (config->type) { case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) changed = 1; @@ -198,7 +198,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -212,7 +212,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_MIDI: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -224,7 +224,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case CONFIG_FNAME: { - char* str = config_get_string(config_device->name, config->name, (char*)""); + char* str = config_get_string((char *) config_device->name, (char *) config->name, (char*)""); SendMessage(h, WM_GETTEXT, 511, (LPARAM)s); if (strcmp(str, s)) changed = 1; @@ -234,7 +234,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_SPINNER: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); if (val_int > config->spinner.max) val_int = config->spinner.max; else if (val_int < config->spinner.min) @@ -251,7 +251,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_HEX16: - val_int = config_get_hex16(config_device->name, config->name, config->default_int); + val_int = config_get_hex16((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -265,7 +265,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_HEX20: - val_int = config_get_hex20(config_device->name, config->name, config->default_int); + val_int = config_get_hex20((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -301,7 +301,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) switch (config->type) { case CONFIG_BINARY: - config_set_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0)); + config_set_int((char *) config_device->name, (char *) config->name, SendMessage(h, BM_GETCHECK, 0, 0)); id++; break; @@ -310,21 +310,21 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_int(config_device->name, config->name, selection->value); + config_set_int((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; case CONFIG_MIDI: c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int(config_device->name, config->name, c); + config_set_int((char *) config_device->name, (char *) config->name, c); id += 2; break; case CONFIG_FNAME: SendMessage(h, WM_GETTEXT, 511, (LPARAM)ws); - config_set_wstring(config_device->name, config->name, ws); + config_set_wstring((char *) config_device->name, (char *) config->name, ws); id += 3; break; @@ -337,7 +337,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) else if (c < config->spinner.min) c = config->spinner.min; - config_set_int(config_device->name, config->name, c); + config_set_int((char *) config_device->name, (char *) config->name, c); id += 2; break; @@ -346,7 +346,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_hex16(config_device->name, config->name, selection->value); + config_set_hex16((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; @@ -355,7 +355,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_hex20(config_device->name, config->name, selection->value); + config_set_hex20((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 36e1c25ad..7a3774941 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.38 2018/02/07 + * Version: @(#)win_settings.c 1.0.39 2018/02/18 * * Author: Miran Grca, * @@ -545,7 +545,7 @@ static void win_settings_machine_recalc_cpu_m(HWND hdlg) c = 0; while (machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) { - stransi = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + stransi = (char *) machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].name; mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); c++; diff --git a/src/zip.c b/src/zip.c index c688d25f6..f6726f413 100644 --- a/src/zip.c +++ b/src/zip.c @@ -455,6 +455,7 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = static mode_sense_pages_t zip_mode_sense_pages_saved[ZIP_NUM]; +#define ENABLE_ZIP_LOG 1 #ifdef ENABLE_ZIP_LOG int zip_do_log = ENABLE_ZIP_LOG; #endif @@ -1424,9 +1425,6 @@ void zip_command(uint8_t id, uint8_t *cdb) int32_t *BufLen; uint32_t i = 0; -#if 0 - int CdbLength; -#endif if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; zip[id].status &= ~ERR_STAT; @@ -1446,10 +1444,9 @@ void zip_command(uint8_t id, uint8_t *cdb) zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], zip_sense_key, zip_asc, zip_ascq, zip[id].unit_attention); zip_log("ZIP %i: Request length: %04X\n", id, zip[id].request_length); -#if 0 - for (CdbLength = 1; CdbLength < zip[id].cdb_len; CdbLength++) - zip_log("ZIP %i: CDB[%d] = %d\n", id, CdbLength, cdb[CdbLength]); -#endif + zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, + cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11]); } zip[id].sector_len = 0;