diff --git a/src/devices/network/network.c b/src/devices/network/network.c index e5d2785..085a467 100644 --- a/src/devices/network/network.c +++ b/src/devices/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.10 2018/05/24 + * Version: @(#)network.c 1.0.11 2018/06/10 * * Author: Fred N. van Kempen, * @@ -54,7 +54,7 @@ #include #include #include -#ifdef WALTJE +#ifdef ENABLE_NETWORK_DUMP # include #endif #define HAVE_STDARG_H @@ -102,47 +102,10 @@ static struct { } poll_data; -#ifdef WALTJE +#ifdef ENABLE_NETWORK_DUMP # define is_print(c) (isalnum((int)(c)) || ((c) == ' ')) -#if 0 -/* Dump a buffer in hex, standard output. */ -static void -hexdump(uint8_t *bufp, int len) -{ - char asci[20]; - uint8_t c; - int addr; - - addr = 0; - while (len-- > 0) { - c = bufp[addr]; - if ((addr % 16) == 0) { - printf("%06X %02X", addr, c); - } else { - printf(" %02X", c); - } - asci[(addr & 15)] = (char)((is_print(c) ? c : '.') & 0xff); - if ((++addr % 16) == 0) { - asci[16] = '\0'; - printf(" | %s |\n", asci); - } - } - - if (addr % 16) { - while (addr % 16) { - printf(" "); - asci[(addr & 15)] = ' '; - addr++; - } - asci[16] = '\0'; - printf(" | %s |\n", asci); - } -} -#endif - - /* Dump a buffer in hex to output buffer. */ static void hexdump_p(char *ptr, uint8_t *bufp, int len) @@ -403,9 +366,9 @@ network_tx(uint8_t *bufp, int len) { ui_sb_icon_update(SB_NETWORK, 1); -#ifdef WALTJE +#ifdef ENABLE_NETWORK_DUMP { - char temp[4096]; + char temp[8192]; hexdump_p(temp, bufp, len); pclog("NETWORK: >> len=%d\n%s\n", len, temp); } diff --git a/src/devices/video/vid_ati28800.c b/src/devices/video/vid_ati28800.c index ac0d1dd..ae554fc 100644 --- a/src/devices/video/vid_ati28800.c +++ b/src/devices/video/vid_ati28800.c @@ -8,12 +8,12 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.13 2018/05/06 + * Version: @(#)vid_ati28800.c 1.0.14 2018/06/11 * * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, - * greatpsycho, + * greatpsycho, * * Copyright 2017,2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. @@ -69,8 +69,7 @@ #define BIOS_ROM_PATH L"video/ati/ati28800/bios.bin" -typedef struct ati28800_t -{ +typedef struct { svga_t svga; ati_eeprom_t eeprom; @@ -91,289 +90,314 @@ typedef struct ati28800_t } ati28800_t; -static void ati28800_out(uint16_t addr, uint8_t val, void *p) +static void +ati28800_out(uint16_t addr, uint8_t val, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t old; - -/* pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); */ - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; + ati28800_t *ati = (ati28800_t *)p; + svga_t *svga = &ati->svga; + uint8_t old; + +#if 0 + pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); +#endif + + if (((addr&0xFFF0) == 0x3D0 || + (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) + addr ^= 0x60; + + switch (addr) { + case 0x1ce: + ati->index = val; + break; + + case 0x1cf: + old = ati->regs[ati->index]; + ati->regs[ati->index] = val; + switch (ati->index) { + case 0xb2: + case 0xbe: + if (ati->regs[0xbe] & 8) /*Read/write bank mode*/ { + svga->read_bank = ((ati->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ati->regs[0xb2] >> 1) & 7) * 0x10000; + break; + + case 0xb3: + ati_eeprom_write(&ati->eeprom, val & 8, val & 2, val & 1); + break; - switch (addr) - { - case 0x1ce: - ati28800->index = val; - break; - case 0x1cf: - old=ati28800->regs[ati28800->index]; - ati28800->regs[ati28800->index] = val; - switch (ati28800->index) - { - case 0xb2: - case 0xbe: - if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - } - else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - break; - case 0xb3: - ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); - break; case 0xb6: - if((old ^ val) & 0x10) svga_recalctimings(svga); - break; - case 0xb8: - if((old ^ val) & 0x40) svga_recalctimings(svga); - break; - case 0xb9: - if((old ^ val) & 2) svga_recalctimings(svga); - } - 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); -} + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; -static void ati28800k_out(uint16_t addr, uint8_t val, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; + case 0xb8: + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + break; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1CF: - if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) - { - ati28800->ksc5601_mode_enabled = val & 0x20; - svga_recalctimings(svga); - - } - ati28800_out(oldaddr, val, p); - break; - case 0x3DD: - ati28800->port_03dd_val = val; - if (val == 1) ati28800->get_korean_font_enabled = 0; - if (ati28800->in_get_korean_font_kind_set) - { - ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); - ati28800->get_korean_font_enabled = 1; - ati28800->get_korean_font_index = 0; - ati28800->in_get_korean_font_kind_set = 0; - } - break; - case 0x3DE: - ati28800->in_get_korean_font_kind_set = 0; - if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) - { - if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; - ati28800->get_korean_font_index++; - ati28800->get_korean_font_index &= 0x1F; - } - else - { - switch(ati28800->port_03dd_val) - { - case 0x10: - ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); - break; - case 8: - ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; - if(val & 2) - ati28800->in_get_korean_font_kind_set = 1; - break; - } - break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); } - default: - ati28800_out(oldaddr, val, p); - break; - } + 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 ati28800_in(uint16_t addr, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t temp; -/* if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); */ - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - temp = ati28800->index; - break; - case 0x1cf: - switch (ati28800->index) - { +static void +ati28800k_out(uint16_t addr, uint8_t val, void *p) +{ + ati28800_t *ati = (ati28800_t *)p; + svga_t *svga = &ati->svga; + uint16_t oldaddr = addr; + + if (((addr&0xFFF0) == 0x3D0 || + (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) + addr ^= 0x60; + + switch (addr) { + case 0x1CF: + if (ati->index == 0xBF && ((ati->regs[0xBF] ^ val) & 0x20)) { + ati->ksc5601_mode_enabled = val & 0x20; + svga_recalctimings(svga); + + } + ati28800_out(oldaddr, val, p); + break; + + case 0x3DD: + ati->port_03dd_val = val; + if (val == 1) ati->get_korean_font_enabled = 0; + if (ati->in_get_korean_font_kind_set) { + ati->get_korean_font_kind = (val << 8) | (ati->get_korean_font_kind & 0xFF); + ati->get_korean_font_enabled = 1; + ati->get_korean_font_index = 0; + ati->in_get_korean_font_kind_set = 0; + } + break; + + case 0x3DE: + ati->in_get_korean_font_kind_set = 0; + if (ati->get_korean_font_enabled && (ati->regs[0xBF] & 0x20)) { + if ((ati->get_korean_font_base & 0x7F) > 0x20 && (ati->get_korean_font_base & 0x7F) < 0x7F) + fontdatksc5601_user[(ati->get_korean_font_kind & 4) * 24 + (ati->get_korean_font_base & 0x7F) - 0x20].chr[ati->get_korean_font_index] = val; + ati->get_korean_font_index++; + ati->get_korean_font_index &= 0x1F; + } else { + switch(ati->port_03dd_val) { + case 0x10: + ati->get_korean_font_base = ((val & 0x7F) << 7) | (ati->get_korean_font_base & 0x7F); + break; + + case 8: + ati->get_korean_font_base = (ati->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati->get_korean_font_kind = (ati->get_korean_font_kind & 0xFF00) | val; + if (val & 2) + ati->in_get_korean_font_kind_set = 1; + break; + } + } + break; + + default: + ati28800_out(oldaddr, val, p); + break; + } +} + + +static uint8_t +ati28800_in(uint16_t addr, void *p) +{ + ati28800_t *ati = (ati28800_t *)p; + svga_t *svga = &ati->svga; + uint8_t temp; + +#if 0 + if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); +#endif + + if (((addr&0xFFF0) == 0x3D0 || + (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; + + switch (addr) { + case 0x1ce: + temp = ati->index; + break; + + case 0x1cf: + switch (ati->index) { case 0xb0: - if (ati28800->memory == 256) - return 0x08; - else if (ati28800->memory == 512) - return 0x10; - else - return 0x18; - break; + if (ati->memory == 256) + return 0x08; + else if (ati->memory == 512) + return 0x10; + else + return 0x18; + break; - case 0xb7: - temp = ati28800->regs[ati28800->index] & ~8; - if (ati_eeprom_read(&ati28800->eeprom)) - temp |= 8; - break; - - default: - temp = ati28800->regs[ati28800->index]; - break; - } - break; + case 0xb7: + temp = ati->regs[ati->index] & ~8; + if (ati_eeprom_read(&ati->eeprom)) + temp |= 8; + break; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - break; - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } - /* if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); */ - return temp; + default: + temp = ati->regs[ati->index]; + break; + } + break; + + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + temp = 0; + else + temp = 0x10; + break; + + case 0x3D4: + temp = svga->crtcreg; + break; + + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + + default: + temp = svga_in(addr, svga); + break; + } +#if 0 + if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); +#endif + + return temp; } -static uint8_t ati28800k_in(uint16_t addr, void *p) + +static uint8_t +ati28800k_in(uint16_t addr, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - uint8_t temp = 0xFF; + ati28800_t *ati = (ati28800_t *)p; + svga_t *svga = &ati->svga; + uint16_t oldaddr = addr; + uint8_t temp = 0xFF; -// if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; - - switch (addr) - { - case 0x3DE: - if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) - { - switch(ati28800->get_korean_font_kind >> 8) - { - case 4: /* ROM font */ - temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; - break; - case 2: /* User defined font */ - if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; - else - temp = 0xFF; - ati28800->get_korean_font_index++; - break; - default: - break; - } - ati28800->get_korean_font_index &= 0x1F; - } - break; - default: - temp = ati28800_in(oldaddr, p); - break; - } - if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; +#if 0 + if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); +#endif + + if (((addr&0xFFF0) == 0x3D0 || + (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; + + switch (addr) { + case 0x3DE: + if (ati->get_korean_font_enabled && (ati->regs[0xBF] & 0x20)) { + switch(ati->get_korean_font_kind >> 8) { + case 4: /* ROM font */ + temp = fontdatksc5601[ati->get_korean_font_base].chr[ati->get_korean_font_index++]; + break; + + case 2: /* User defined font */ + if ((ati->get_korean_font_base & 0x7F) > 0x20 && (ati->get_korean_font_base & 0x7F) < 0x7F) + temp = fontdatksc5601_user[(ati->get_korean_font_kind & 4) * 24 + (ati->get_korean_font_base & 0x7F) - 0x20].chr[ati->get_korean_font_index]; + else + temp = 0xFF; + ati->get_korean_font_index++; + break; + + default: + break; + } + ati->get_korean_font_index &= 0x1F; + } + break; + + default: + temp = ati28800_in(oldaddr, p); + break; + } +#ifdef _DEBUG + if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); +#endif + + return temp; } -static void ati28800_recalctimings(svga_t *svga) + +static void +ati28800_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *)svga->p; + ati28800_t *ati = (ati28800_t *)svga->p; - switch(((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) - { - case 0x00: svga->clock = cpuclock / 42954000.0; break; - case 0x01: svga->clock = cpuclock / 48771000.0; break; - case 0x03: svga->clock = cpuclock / 36000000.0; break; - case 0x04: svga->clock = cpuclock / 50350000.0; break; - case 0x05: svga->clock = cpuclock / 56640000.0; break; - case 0x07: svga->clock = cpuclock / 44900000.0; break; - case 0x08: svga->clock = cpuclock / 30240000.0; break; - case 0x09: svga->clock = cpuclock / 32000000.0; break; - case 0x0A: svga->clock = cpuclock / 37500000.0; break; - case 0x0B: svga->clock = cpuclock / 39000000.0; break; - case 0x0C: svga->clock = cpuclock / 40000000.0; break; - case 0x0D: svga->clock = cpuclock / 56644000.0; break; - case 0x0E: svga->clock = cpuclock / 75000000.0; break; - case 0x0F: svga->clock = cpuclock / 65000000.0; break; - default: break; - } + switch(((ati->regs[0xbe] & 0x10) >> 1) | ((ati->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { + case 0x00: svga->clock = cpuclock / 42954000.0; break; + case 0x01: svga->clock = cpuclock / 48771000.0; break; + case 0x03: svga->clock = cpuclock / 36000000.0; break; + case 0x04: svga->clock = cpuclock / 50350000.0; break; + case 0x05: svga->clock = cpuclock / 56640000.0; break; + case 0x07: svga->clock = cpuclock / 44900000.0; break; + case 0x08: svga->clock = cpuclock / 30240000.0; break; + case 0x09: svga->clock = cpuclock / 32000000.0; break; + case 0x0A: svga->clock = cpuclock / 37500000.0; break; + case 0x0B: svga->clock = cpuclock / 39000000.0; break; + case 0x0C: svga->clock = cpuclock / 40000000.0; break; + case 0x0D: svga->clock = cpuclock / 56644000.0; break; + case 0x0E: svga->clock = cpuclock / 75000000.0; break; + case 0x0F: svga->clock = cpuclock / 65000000.0; break; + default: break; + } - if(ati28800->regs[0xb8] & 0x40) svga->clock *= 2; + if (ati->regs[0xb8] & 0x40) svga->clock *= 2; - if (ati28800->regs[0xb6] & 0x10) - { - svga->hdisp <<= 1; - svga->htotal <<= 1; - svga->rowoffset <<= 1; - } - - if(svga->crtc[0x17] & 4) - { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } + if (ati->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + } - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; - } + if (svga->crtc[0x17] & 4) { + svga->vtotal <<= 1; + svga->dispend <<= 1; + svga->vsyncstart <<= 1; + svga->split <<= 1; + svga->vblankstart <<= 1; + } + + if (!svga->scrblank && (ati->regs[0xb0] & 0x20)) { + /* Extended 256 color modes. */ + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + svga->rowoffset <<= 1; + svga->ma <<= 1; + } } + static void * ati28800_init(const device_t *info) { @@ -413,9 +437,9 @@ ati28800_init(const device_t *info) svga_init(&ati->svga, ati, ati->memory << 10, /*default: 512kb*/ ati28800_recalctimings, - ati28800_in, ati28800_out, - NULL, - NULL); + ati28800_in, ati28800_out, + NULL, + NULL); io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, @@ -431,53 +455,60 @@ ati28800_init(const device_t *info) return(ati); } -void ati28800k_recalctimings(svga_t *svga) + +static void +ati28800k_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *) svga->p; + ati28800_t *ati = (ati28800_t *) svga->p; - ati28800_recalctimings(svga); + ati28800_recalctimings(svga); - if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) - { - svga->render = svga_render_text_80_ksc5601; - } + if (svga->render == svga_render_text_80 && ati->ksc5601_mode_enabled) { + svga->render = svga_render_text_80_ksc5601; + } } -void * + +static void * ati28800k_init(const device_t *info) { - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); + ati28800_t *ati = malloc(sizeof(ati28800_t)); + memset(ati, 0, sizeof(ati28800_t)); - ati28800->memory = device_get_config_int("memory"); + ati->memory = device_get_config_int("memory"); - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; - ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; + ati->port_03dd_val = 0; + ati->get_korean_font_base = 0; + ati->get_korean_font_index = 0; + ati->get_korean_font_enabled = 0; + ati->get_korean_font_kind = 0; + ati->in_get_korean_font_kind_set = 0; + ati->ksc5601_mode_enabled = 0; - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_PATH, 6); + rom_init(&ati->bios_rom, BIOS_ATIKOR_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_PATH, 6); - svga_init(&ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); + svga_init(&ati->svga, ati, + ati->memory << 10, /*Memory size, default 512KB*/ + ati28800k_recalctimings, + ati28800k_in, ati28800k_out, + NULL, + NULL); - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x01ce, 2, + ati28800k_in,NULL,NULL, ati28800k_out,NULL,NULL, ati); + io_sethandler(0x03c0, 32, + ati28800k_in,NULL,NULL, ati28800k_out,NULL,NULL, ati); - ati28800->svga.miscout = 1; + ati->svga.miscout = 1; - ati_eeprom_load(&ati28800->eeprom, L"atikorvga.nvr", 0); + ati_eeprom_load(&ati->eeprom, L"atikorvga.nvr", 0); - return ati28800; + return(ati); } + static int ati28800_available(void) { @@ -525,9 +556,9 @@ ati28800_close(void *priv) static void ati28800_speed_changed(void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - - svga_recalctimings(&ati28800->svga); + ati28800_t *ati = (ati28800_t *)p; + + svga_recalctimings(&ati->svga); } @@ -549,9 +580,10 @@ static void ati28800_add_status_info(char *s, int max_len, void *priv) void ati28800k_add_status_info(char *s, int max_len, void *p) { char temps[128]; - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati = (ati28800_t *)p; - sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", + ati->ksc5601_mode_enabled ? "Yes" : "No"); strncat(s, temps, max_len); ati28800_add_status_info(s, max_len, p); @@ -560,51 +592,51 @@ void ati28800k_add_status_info(char *s, int max_len, void *p) static const device_config_t ati28800_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1024 kB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, + { + { + "256 kB", 256 + }, + { + "512 kB", 512 + }, + { + "1024 kB", 1024 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; #if defined(DEV_BRANCH) && defined(USE_XL24) static const device_config_t ati28800_wonderxl_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } + { + "memory", "Memory size", CONFIG_SELECTION, "", 512, + { + { + "256 kB", 256 + }, + { + "512 kB", 512 + }, + { + "1 MB", 1024 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; #endif diff --git a/src/machines/m_at_scat.c b/src/machines/m_at_scat.c index bac3b7a..cca19a9 100644 --- a/src/machines/m_at_scat.c +++ b/src/machines/m_at_scat.c @@ -10,7 +10,7 @@ * * Re-worked version based on the 82C235 datasheet and errata. * - * Version: @(#)m_at_scat.c 1.0.8 2018/05/06 + * Version: @(#)m_at_scat.c 1.0.9 2018/06/12 * * Authors: Fred N. van Kempen, * Original by GreatPsycho for PCem. @@ -76,53 +76,92 @@ #define SCATSX_CAS_TIMING_FOR_DMA 0x64 -typedef struct scat_t { +typedef struct { uint8_t regs_2x8; uint8_t regs_2x9; } scat_t; -static uint8_t scat_regs[256]; -static int scat_index; -static uint8_t scat_port_92 = 0; -static uint8_t scat_ems_reg_2xA = 0; -static scat_t scat_stat[32]; -static uint32_t scat_xms_bound; -static mem_mapping_t scat_mapping[32]; -static mem_mapping_t scat_high_mapping[16]; -static mem_mapping_t scat_shadowram_mapping[6]; -static mem_mapping_t scat_4000_9FFF_mapping[24]; -static mem_mapping_t scat_A000_BFFF_mapping; +static uint8_t scat_regs[256]; +static int scat_index; +static uint8_t scat_port_92 = 0; +static uint8_t scat_ems_reg_2xA = 0; +static scat_t scat_stat[32]; +static uint32_t scat_xms_bound; +static mem_mapping_t scat_low_mapping[32]; +static mem_mapping_t scat_ems_mapping[32]; +static mem_mapping_t scat_high_mapping[16]; +static mem_mapping_t scat_remap_mapping[6]; +static mem_mapping_t scat_4000_EFFF_mapping[44]; +static mem_mapping_t scat_low_ROMCS_mapping[8]; -// TODO - 82C836 chipset's memory address mapping isn't fully implemented yet, so memory configuration is hardcoded now. -static int scatsx_mem_conf_val[33] = { - 0x00, 0x01, 0x03, 0x04, 0x05, 0x08, 0x06, 0x06, - 0x0c, 0x09, 0x07, 0x07, 0x0d, 0x0a, 0x0f, 0x0f, - 0x0e, 0x0e, 0x10, 0x10, 0x13, 0x13, 0x11, 0x11, - 0x14, 0x14, 0x12, 0x12, 0x15, 0x15, 0x15, 0x15, - 0x16 + +static const uint8_t scat_max_map[32] = { + 0, 1, 1, 1, 2, 3, 4, 8, + 4, 8, 12, 16, 20, 24, 28, 32, + 0, 5, 9, 13, 6, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; +static const uint8_t scatsx_max_map[32] = { + 0, 1, 2, 1, 3, 4, 6, 10, + 5, 9, 13, 4, 8, 12, 16, 14, + 18, 22, 26, 20, 24, 28, 32, 18, + 20, 32, 0, 0, 0, 0, 0, 0 +}; + +static const uint8_t scatsx_external_is_RAS[33] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0 +}; + + +static int external_is_RAS = 0; + static uint8_t scat_read(uint16_t port, void *priv); static void scat_write(uint16_t port, uint8_t val, void *priv); + static void -scat_shadow_state_update(void) +romcs_state_update(uint8_t val) +{ + int i; + + for (i = 0; i < 4; i++) { + if (val & 1) { + mem_mapping_enable(&scat_low_ROMCS_mapping[i << 1]); + mem_mapping_enable(&scat_low_ROMCS_mapping[(i << 1) + 1]); + } else { + mem_mapping_disable(&scat_low_ROMCS_mapping[i << 1]); + mem_mapping_disable(&scat_low_ROMCS_mapping[(i << 1) + 1]); + } + val >>= 1; + } + + for (i = 0; i < 4; i++) { + if (val & 1) { + mem_mapping_enable(&bios_mapping[i << 1]); + mem_mapping_enable(&bios_mapping[(i << 1) + 1]); + } else { + mem_mapping_disable(&bios_mapping[i << 1]); + mem_mapping_disable(&bios_mapping[(i << 1) + 1]); + } + val >>= 1; + } +} + + +static void +shadow_state_update(void) { int i, val; - // TODO - ROMCS enable features should be implemented later. for (i = 0; i < 24; i++) { - val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL; - if (i < 8) { - val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; - } else { - if ((scat_regs[SCAT_RAM_WRITE_PROTECT] >> ((i - 8) >> 1)) & 1) - val |= MEM_WRITE_DISABLED; - else - val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; - } + val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; mem_set_mem_state((i + 40) << 14, 0x4000, val); } @@ -131,12 +170,12 @@ scat_shadow_state_update(void) static void -scat_set_xms_bound(uint8_t val) +set_xms_bound(uint8_t val) { - uint32_t max_xms_size = (mem_size >= 16128) ? (((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) ? 0xFE0000 : 0xFC0000) : mem_size << 10; + uint32_t max_xms_size = ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0xFE0000 : 0xFC0000; int i; - switch (val & 0x0f) { + switch (val & 0x0F) { case 1: scat_xms_bound = 0x100000; break; @@ -203,109 +242,677 @@ scat_set_xms_bound(uint8_t val) } if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { - if (val != 1) { - if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); - for(i=0;i<6;i++) - mem_mapping_enable(&scat_shadowram_mapping[i]); - if ((val & 0x0F) == 0) - scat_xms_bound = 0x160000; - } else { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_shadowram_mapping[i]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - } - pclog("SCAT: set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); + if((val & 0x0F) == 0 || scat_xms_bound > 0x160000) + scat_xms_bound = 0x160000; if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if (scat_xms_bound < 0x160000) mem_set_mem_state(scat_xms_bound, 0x160000 - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } else { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_shadowram_mapping[i]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - if (scat_xms_bound > max_xms_size) scat_xms_bound = max_xms_size; - pclog("SCAT: set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if (scat_xms_bound < ((uint32_t)mem_size << 10)) + if (scat_xms_bound < (mem_size << 10)) mem_set_mem_state(scat_xms_bound, (mem_size << 10) - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } + + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0x60000 : 0x40000); + if (scat_regs[SCAT_VERSION] & 0xF0) { + for (i = 0; i < 8; i++) { + if (val & 0x10) + mem_mapping_disable(&scat_high_mapping[i]); + else + mem_mapping_enable(&scat_high_mapping[i]); + } + } } static uint32_t get_scat_addr(uint32_t addr, scat_t *p) { + int nbank; + if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) - addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); - else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { - addr &= ~0x600000; - if(mem_size > 2048 || ((uint32_t)mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 6)) - addr |= (addr & 0x180000) << 2; + switch((scat_regs[SCAT_EXTENDED_BOUNDARY] & ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 0x40 : 0)) | (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F)) { + case 0x41: + nbank = addr >> 19; + if (nbank < 4) + nbank = 1; + else if (nbank == 4) + nbank = 0; + else + nbank -= 3; + break; + + case 0x42: + nbank = addr >> 19; + if (nbank < 8) + nbank = 1 + (nbank >> 2); + else if (nbank == 8) + nbank = 0; + else + nbank -= 6; + break; + + case 0x43: + nbank = addr >> 19; + if (nbank < 12) + nbank = 1 + (nbank >> 2); + else if (nbank == 12) + nbank = 0; + else + nbank -= 9; + break; + + case 0x44: + nbank = addr >> 19; + if (nbank < 4) + nbank = 2; + else if (nbank < 6) + nbank -= 4; + else + nbank -= 3; + break; + + case 0x45: + nbank = addr >> 19; + if (nbank < 8) + nbank = 2 + (nbank >> 2); + else if (nbank < 10) + nbank -= 8; + else + nbank -= 6; + break; + + default: + nbank = addr >> (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) ? 19 : 21); + break; + } + nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; + + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && + (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && nbank == 2 && + (addr & 0x7FFFF) < 0x60000 && mem_size > 640) { + nbank = 1; + addr ^= 0x70000; } - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) - addr ^= (uint32_t)mem_size < 2048 ? 0x1F0000 : 0x670000; - } else { - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) - addr ^= 0x1F0000; - } + if (external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { + if (nbank == 3) + nbank = 7; + else + return 0xFFFFFFFF; + } else if (!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { + switch(nbank) { + case 7: + nbank = 3; + break; + /* Note - In the following cases, the chipset accesses multiple memory banks + at the same time, so it's impossible to predict which memory bank + is actually accessed. */ + case 5: + case 1: + nbank = 1; + break; + + case 3: + nbank = 2; + break; + + default: + nbank = 0; + break; + } + } + + if ((scat_regs[SCAT_VERSION] & 0x0F) > 3 && + (mem_size > 2048) && (mem_size & 1536)) { + if ((mem_size & 1536) == 512) { + if (nbank == 0) + addr &= 0x7FFFF; + else + addr = 0x80000 + ((addr & 0x1FFFFF) | ((nbank - 1) << 21)); + } else { + if (nbank < 2) + addr = (addr & 0x7FFFF) | (nbank << 19); + else + addr = 0x100000 + ((addr & 0x1FFFFF) | ((nbank - 2) << 21)); + } + } else { + int nbanks_2048k, nbanks_512k; + + if (mem_size <= ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 2048 : 4096) && (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8) || external_is_RAS)) { + nbanks_2048k = 0; + nbanks_512k = mem_size >> 9; + } else { + nbanks_2048k = mem_size >> 11; + nbanks_512k = (mem_size & 1536) >> 9; + } + + if (nbank < nbanks_2048k || (nbanks_2048k > 0 && nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7))) { + addr &= 0x1FFFFF; + addr |= (nbank << 21); + } else if (nbank < nbanks_2048k + nbanks_512k || nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7)) { + addr &= 0x7FFFF; + addr |= (nbanks_2048k << 21) | ((nbank - nbanks_2048k) << 19); + } else { + addr &= 0x1FFFF; + addr |= (nbanks_2048k << 21) | (nbanks_512k << 19) | ((nbank - nbanks_2048k - nbanks_512k) << 17); + } + } + } else { + uint32_t addr2; + + switch (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) { + case 2: + case 4: + nbank = addr >> 19; + if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else + addr2 = addr >> 10; + break; + + case 3: + nbank = addr >> 19; + if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) == 2 && (addr & 0x7FFFF) < 0x60000) { + addr ^= 0x1F0000; + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else + addr2 = addr >> 10; + break; + + case 5: + nbank = addr >> 19; + if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { + nbank = (addr >> 10) & 3; + addr2 = addr >> 12; + } else + addr2 = addr >> 10; + break; + + case 6: + nbank = addr >> 19; + if (nbank < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else { + nbank = 2 + ((addr - 0x100000) >> 21); + addr2 = (addr - 0x100000) >> 11; + } + break; + + case 7: + case 0x0F: + nbank = addr >> 19; + if (nbank < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else if (nbank < 10) { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } else { + nbank = 4 + ((addr - 0x500000) >> 21); + addr2 = (addr - 0x500000) >> 11; + } + break; + + case 8: + nbank = addr >> 19; + if (nbank < 4) { + nbank = 1; + addr2 = addr >> 11; + } else if (nbank == 4) { + nbank = 0; + addr2 = addr >> 10; + } else { + nbank -= 3; + addr2 = addr >> 10; + } + break; + case 9: + nbank = addr >> 19; + if (nbank < 8) { + nbank = 1 + ((addr >> 11) & 1); + addr2 = addr >> 12; + } else if (nbank == 8) { + nbank = 0; + addr2 = addr >> 10; + } else { + nbank -= 6; + addr2 = addr >> 10; + } + break; + + case 0x0A: + nbank = addr >> 19; + if (nbank < 8) { + nbank = 1 + ((addr >> 11) & 1); + addr2 = addr >> 12; + } else if (nbank < 12) { + nbank = 3; + addr2 = addr >> 11; + } else if (nbank == 12) { + nbank = 0; + addr2 = addr >> 10; + } else { + nbank -= 9; + addr2 = addr >> 10; + } + break; + + case 0x0B: + nbank = addr >> 21; + addr2 = addr >> 11; + break; + + case 0x0C: + case 0x0D: + nbank = addr >> 21; + if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { + nbank = (addr >> 11) & 1; + addr2 = addr >> 12; + } else + addr2 = addr >> 11; + break; + + case 0x0E: + case 0x13: + nbank = addr >> 21; + if ((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { + nbank = (addr >> 11) & 3; + addr2 = addr >> 13; + } else + addr2 = addr >> 11; + break; + + case 0x10: + case 0x11: + nbank = addr >> 19; + if (nbank < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else if (nbank < 10) { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } else if (nbank < 18) { + nbank = 4 + (((addr - 0x500000) >> 11) & 1); + addr2 = (addr - 0x500000) >> 12; + } else { + nbank = 6 + ((addr - 0x900000) >> 21); + addr2 = (addr - 0x900000) >> 11; + } + break; + + case 0x12: + nbank = addr >> 19; + if (nbank < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else if (nbank < 10) { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } else { + nbank = 4 + (((addr - 0x500000) >> 11) & 3); + addr2 = (addr - 0x500000) >> 13; + } + break; + + case 0x14: + case 0x15: + nbank = addr >> 21; + if ((nbank & 7) < 4) { + nbank = (addr >> 11) & 3; + addr2 = addr >> 13; + } else if ((nbank & 7) < 6) { + nbank = 4 + (((addr - 0x800000) >> 11) & 1); + addr2 = (addr - 0x800000) >> 12; + } else { + nbank = 6 + (((addr - 0xC00000) >> 11) & 3); + addr2 = (addr - 0xC00000) >> 13; + } + break; + + case 0x16: + nbank = ((addr >> 21) & 4) | ((addr >> 11) & 3); + addr2 = addr >> 13; + break; + + case 0x17: + if (external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 19; + if (nbank < 2) { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } else { + nbank = 2 + ((addr - 0x100000) >> 23); + addr2 = (addr - 0x100000) >> 12; + } + break; + + case 0x18: + if (external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 21; + if (nbank < 4) { + nbank = 1; + addr2 = addr >> 12; + } else if (nbank == 4) { + nbank = 0; + addr2 = addr >> 11; + } else { + nbank -= 3; + addr2 = addr >> 11; + } + break; + + case 0x19: + if (external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 23; + if ((nbank & 3) < 2) { + nbank = (addr >> 12) & 1; + addr2 = addr >> 13; + } else + addr2 = addr >> 12; + break; + + default: + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6) { + nbank = addr >> 19; + addr2 = (addr >> 10) & 0x1FF; + } else if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) { + nbank = addr >> 21; + addr2 = (addr >> 11) & 0x3FF; + } else { + nbank = addr >> 23; + addr2 = (addr >> 12) & 0x7FF; + } + break; + } + + nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 0x16 && nbank == 3) + return 0xFFFFFFFF; + + if (external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { + if (nbank == 3) + nbank = 7; + else + return 0xFFFFFFFF; + } else if (!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { + switch(nbank) { + case 7: + nbank = 3; + break; + + /* Note - In the following cases, the chipset accesses multiple memory banks + at the same time, so it's impossible to predict which memory bank + is actually accessed. */ + case 5: + case 1: + nbank = 1; + break; + + case 3: + nbank = 2; + break; + + default: + nbank = 0; + break; + } + } + + switch(mem_size & ~511) { + case 1024: + case 1536: + addr &= 0x3FF; + if (nbank < 2) + addr |= (nbank << 10) | ((addr2 & 0x1FF) << 11); + else + addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); + break; + + case 2048: + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 5) { + addr &= 0x3FF; + if (nbank < 4) + addr |= (nbank << 10) | ((addr2 & 0x1FF) << 12); + else + addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); + } else { + addr &= 0x7FF; + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } + break; + + case 2560: + if (nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); + } + break; + + case 3072: + if (nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + + case 4096: + case 6144: + addr &= 0x7FF; + if (nbank < 2) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 12); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + + case 4608: + if (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) { + if (nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if (nbank < 3) + addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); + else + addr = 0x480000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 3) << 19)); + } else if (nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); + } + break; + + case 5120: + case 7168: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 4) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + case 6656: + if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) { + if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if(nbank < 3) + addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); + else if(nbank == 3) + addr = 0x480000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11)); + else + addr = 0x680000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 4) << 19)); + } else if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if(nbank == 1) { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + (addr2 << 11); + } else { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x280000 + ((addr2 << 12) | ((nbank & 1) << 11) | (((nbank - 2) & 6) << 21)); + } + break; + case 8192: + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + case 9216: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(external_is_RAS) { + if(nbank < 6) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + } else + addr = 0x100000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); + break; + case 10240: + if(external_is_RAS) { + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } else if(nbank == 0) + addr = (addr & 0x7FF) | ((addr2 & 0x3FF) << 11); + else { + addr &= 0xFFF; + addr2 &= 0x7FF; + addr = addr + 0x200000 + ((addr2 << 12) | ((nbank - 1) << 23)); + } + break; + case 11264: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 6) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + case 12288: + if(external_is_RAS) { + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else if(nbank < 6) + addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } else { + if(nbank < 2) + addr = (addr & 0x7FF) | (nbank << 11) | ((addr2 & 0x3FF) << 12); + else + addr = 0x400000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); + } + break; + case 13312: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 4) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x500000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 13) | ((nbank & 3) << 11)); + break; + case 14336: + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else if(nbank < 6) + addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + case 16384: + if(external_is_RAS) { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr |= ((nbank & 3) << 11) | (addr2 << 13) | ((nbank & 4) << 21); + } else { + addr &= 0xFFF; + addr2 &= 0x7FF; + if(nbank < 2) + addr |= (addr2 << 13) | (nbank << 12); + else + addr |= (addr2 << 12) | (nbank << 23); + } + break; + default: + if(mem_size < 2048 || ((mem_size & 1536) == 512) || (mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6)) { + addr &= 0x3FF; + addr2 &= 0x1FF; + addr |= (addr2 << 10) | (nbank << 19); + } else if(mem_size < 8192 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr |= (addr2 << 11) | (nbank << 21); + } else { + addr &= 0xFFF; + addr2 &= 0x7FF; + addr |= (addr2 << 12) | (nbank << 23); + } + break; + } + } return addr; } static void -scat_memmap_state_update(void) -{ - uint32_t addr; - int i; - - for(i=16;i<24;i++) { - addr = get_scat_addr(0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&scat_4000_9FFF_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - } - - addr = get_scat_addr(0xA0000, NULL); - mem_mapping_set_exec(&scat_A000_BFFF_mapping, addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - for (i=0;i<6;i++) { - addr = get_scat_addr(0x100000 + (i << 16), NULL); - mem_mapping_set_exec(&scat_shadowram_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - } - - flushmmucache(); -} - - -static void -scat_set_global_EMS_state(int state) +set_global_EMS_state(int state) { uint32_t base_addr, virt_addr; int i; for (i=((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 24; i<32; i++) { base_addr = (i + 16) << 14; - if (i >= 24) + if(i >= 24) base_addr += 0x30000; - if (state && (scat_stat[i].regs_2x9 & 0x80)) { + if(state && (scat_stat[i].regs_2x9 & 0x80)) { virt_addr = get_scat_addr(base_addr, &scat_stat[i]); - if (i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); - mem_mapping_enable(&scat_mapping[i]); - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&scat_mapping[i], ram+virt_addr); - else - mem_mapping_set_exec(&scat_mapping[i], NULL); + if(i < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); + mem_mapping_enable(&scat_ems_mapping[i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[i], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[i], NULL); } else { - mem_mapping_set_exec(&scat_mapping[i], ram + base_addr); - mem_mapping_disable(&scat_mapping[i]); - if (i < 24) - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + mem_mapping_set_exec(&scat_ems_mapping[i], ram + base_addr); + mem_mapping_disable(&scat_ems_mapping[i]); + + int conf = (scat_regs[SCAT_VERSION] & 0xF0) ? (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) : (scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2); + if(i < 24) { + if(conf > 1 || (conf == 1 && i < 16)) + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + } else if(conf > 3 || ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && conf == 2)) + mem_mapping_enable(&scat_4000_EFFF_mapping[i + 12]); + else + mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); } } @@ -313,12 +920,80 @@ scat_set_global_EMS_state(int state) } +static void +memmap_state_update(void) +{ + uint32_t addr; + int i; + + for (i= (((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 16);i<44;i++) { + addr = get_scat_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&scat_4000_EFFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + addr = get_scat_addr(0, NULL); + mem_mapping_set_exec(&scat_low_mapping[0], addr < (mem_size << 10) ? ram + addr : NULL); + addr = get_scat_addr(0xF0000, NULL); + mem_mapping_set_exec(&scat_low_mapping[1], addr < (mem_size << 10) ? ram + addr : NULL); + + for (i = 2; i < 32; i++) { + addr = get_scat_addr(i << 19, NULL); + mem_mapping_set_exec(&scat_low_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { + for(i=0;i < scat_max_map[(scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)];i++) + mem_mapping_enable(&scat_low_mapping[i]); + for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); + + for(i=24;i<36;i++) { + if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4) + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + } else { + for(i=0;i < scatsx_max_map[scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F];i++) + mem_mapping_enable(&scat_low_mapping[i]); + for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); + + for(i=24;i<36;i++) { + if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 2 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3) + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + } + + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) { + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { + mem_mapping_disable(&scat_low_mapping[2]); + for(i=0;i<6;i++) { + addr = get_scat_addr(0x100000 + (i << 16), NULL); + mem_mapping_set_exec(&scat_remap_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + mem_mapping_enable(&scat_remap_mapping[i]); + } + } else { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_remap_mapping[i]); + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 4) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 3)) + mem_mapping_enable(&scat_low_mapping[2]); + } + } else { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_remap_mapping[i]); + mem_mapping_enable(&scat_low_mapping[2]); + } + + set_global_EMS_state(scat_regs[SCAT_EMS_CONTROL] & 0x80); +} + + static void scat_write(uint16_t port, uint8_t val, void *priv) { uint8_t scat_reg_valid = 0, scat_shadow_update = 0, scat_map_update = 0, index; uint32_t base_addr, virt_addr; - + switch (port) { case 0x22: scat_index = val; @@ -331,115 +1006,97 @@ scat_write(uint16_t port, uint8_t val, void *priv) case SCAT_PERIPHERAL_CONTROL: scat_reg_valid = 1; break; - case SCAT_EMS_CONTROL: - if (val & 0x40) { - if (val & 1) { - io_sethandler(0x0218, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0208, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + if(val & 0x40) { + if(val & 1) { + io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); } else { - io_sethandler(0x0208, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0218, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); } } else { - io_removehandler(0x0208, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_removehandler(0x0218, 3, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); } - scat_set_global_EMS_state(val & 0x80); + set_global_EMS_state(val & 0x80); scat_reg_valid = 1; break; - case SCAT_POWER_MANAGEMENT: - // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. + /* TODO - Only use AUX parity disable bit for this version. + Other bits should be implemented later. */ val &= (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x40 : 0x60; scat_reg_valid = 1; break; - case SCAT_DRAM_CONFIGURATION: - if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) { - if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (val & 0x1F) == 3)) { - if ((uint32_t)mem_size > 1024) - mem_mapping_disable(&ram_high_mapping); - for (index=0;index<6;index++) - mem_mapping_enable(&scat_shadowram_mapping[index]); - } else { - for (index=0;index<6;index++) - mem_mapping_disable(&scat_shadowram_mapping[index]); - if ((uint32_t)mem_size > 1024) - mem_mapping_enable(&ram_high_mapping); - } - } else { - for (index=0;index<6;index++) - mem_mapping_disable(&scat_shadowram_mapping[index]); - if ((uint32_t)mem_size > 1024) - mem_mapping_enable(&ram_high_mapping); - } scat_map_update = 1; - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; cpu_update_waitstates(); - } else { - if (mem_size != 1024 || ((val & 0x1F) != 2 && (val & 0x1F) != 3)) - val = (val & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; } scat_reg_valid = 1; break; - case SCAT_EXTENDED_BOUNDARY: - scat_set_xms_bound(val & ((scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x4f : 0x1f)); + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { + if(scat_regs[SCAT_VERSION] < 4) { + val &= 0xBF; + set_xms_bound(val & 0x0f); + } else { + val = (val & 0x7F) | 0x80; + set_xms_bound(val & 0x4f); + } + } else + set_xms_bound(val & 0x1f); mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if ((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0x40) - scat_map_update = 1; + if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0xC0) scat_map_update = 1; scat_reg_valid = 1; break; - case SCAT_ROM_ENABLE: + scat_reg_valid = 1; + romcs_state_update(val); + break; case SCAT_RAM_WRITE_PROTECT: + scat_reg_valid = 1; + flushmmucache_cr3(); + break; case SCAT_SHADOW_RAM_ENABLE_1: case SCAT_SHADOW_RAM_ENABLE_2: case SCAT_SHADOW_RAM_ENABLE_3: scat_reg_valid = 1; scat_shadow_update = 1; break; - case SCATSX_LAPTOP_FEATURES: - if ((scat_regs[SCAT_VERSION] & 0xF0) != 0) { + if((scat_regs[SCAT_VERSION] & 0xF0) != 0) { val = (val & ~8) | (scat_regs[SCATSX_LAPTOP_FEATURES] & 8); scat_reg_valid = 1; } break; - case SCATSX_FAST_VIDEO_CONTROL: case SCATSX_FAST_VIDEORAM_ENABLE: case SCATSX_HIGH_PERFORMANCE_REFRESH: case SCATSX_CAS_TIMING_FOR_DMA: - if ((scat_regs[SCAT_VERSION] & 0xF0) != 0) - scat_reg_valid = 1; + if((scat_regs[SCAT_VERSION] & 0xF0) != 0) scat_reg_valid = 1; break; - default: break; } if (scat_reg_valid) scat_regs[scat_index] = val; - else - pclog("SCAT: attempted to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); if (scat_shadow_update) - scat_shadow_state_update(); + shadow_state_update(); if (scat_map_update) - scat_memmap_state_update(); -// pclog("SCAT: write Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); + memmap_state_update(); break; case 0x92: if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); + mem_a20_alt = val & 2; + mem_a20_recalc(); } if ((~scat_port_92 & val) & 1) { - softresetx86(); + softresetx86(); cpu_set_edx(); } scat_port_92 = val; @@ -448,73 +1105,56 @@ scat_write(uint16_t port, uint8_t val, void *priv) case 0x208: case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: write EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) - index = scat_ems_reg_2xA & 0x1F; - else - index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x8 = val; base_addr = (index + 16) << 14; - if (index >= 24) + if(index >= 24) base_addr += 0x30000; - if ((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { + if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - else - mem_mapping_set_exec(&scat_mapping[index], NULL); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); flushmmucache(); } } break; - case 0x209: case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: write EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) - index = scat_ems_reg_2xA & 0x1F; - else - index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x9 = val; base_addr = (index + 16) << 14; - if (index >= 24) + if(index >= 24) base_addr += 0x30000; if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { if (val & 0x80) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if (index < 24) - mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - else - mem_mapping_set_exec(&scat_mapping[index], NULL); - mem_mapping_enable(&scat_mapping[index]); -// pclog("SCAT: map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + if(index < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[index]); + else mem_mapping_disable(&scat_4000_EFFF_mapping[index + 12]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); + mem_mapping_enable(&scat_ems_mapping[index]); } else { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if (index < 24) - mem_mapping_enable(&scat_4000_9FFF_mapping[index]); -// pclog("SCAT: unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); + mem_mapping_set_exec(&scat_ems_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_ems_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_EFFF_mapping[index]); + else mem_mapping_enable(&scat_4000_EFFF_mapping[index + 12]); } flushmmucache(); } - if (scat_ems_reg_2xA & 0x80) { + if (scat_ems_reg_2xA & 0x80) scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & (((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0x1f : 3)); - } } break; - case 0x20A: case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: write EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; - } break; } } @@ -524,29 +1164,29 @@ static uint8_t scat_read(uint16_t port, void *priv) { uint8_t val = 0xff, index; - switch (port) { case 0x23: switch (scat_index) { case SCAT_MISCELLANEOUS_STATUS: val = (scat_regs[scat_index] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); break; - case SCAT_DRAM_CONFIGURATION: - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) - val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); - else - if (mem_size != 1024) - val = (scat_regs[scat_index] & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; - else - val = scat_regs[scat_index]; + if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); + else val = scat_regs[scat_index]; + break; + case SCAT_EXTENDED_BOUNDARY: + val = scat_regs[scat_index]; + if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { + if((scat_regs[SCAT_VERSION] & 0x0F) >= 4) + val |= 0x80; + else + val &= 0xAF; + } break; - default: val = scat_regs[scat_index]; break; } -// pclog("SCAT: read Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); break; case 0x92: @@ -556,62 +1196,116 @@ scat_read(uint16_t port, void *priv) case 0x208: case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: read EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) - index = scat_ems_reg_2xA & 0x1F; - else - index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x8; } break; - case 0x209: case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: read EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) - index = scat_ems_reg_2xA & 0x1F; - else - index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x9; } break; - case 0x20A: case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("SCAT: read EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) val = scat_ems_reg_2xA; - } break; } - return val; } static uint8_t -mem_read_scatems(uint32_t addr, void *priv) +mem_read_scatb(uint32_t addr, void *priv) { - scat_t *stat = (scat_t *)priv; uint8_t val = 0xff; + scat_t *stat = (scat_t *)priv; addr = get_scat_addr(addr, stat); - if (addr < ((uint32_t)mem_size << 10)) - val = mem_read_ram(addr, priv); + if (addr < (mem_size << 10)) + val = ram[addr]; return val; } static void -mem_write_scatems(uint32_t addr, uint8_t val, void *priv) +mem_write_scatb(uint32_t addr, uint8_t val, void *priv) { scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; + + addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } + if (addr < (mem_size << 10)) + ram[addr] = val; +} + + +static uint16_t +mem_read_scatw(uint32_t addr, void *priv) +{ + uint16_t val = 0xffff; + scat_t *stat = (scat_t *)priv; addr = get_scat_addr(addr, stat); - if (addr < ((uint32_t)mem_size << 10)) - mem_write_ram(addr, val, priv); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; + + return val; +} + + +static void +mem_write_scatw(uint32_t addr, uint16_t val, void *priv) +{ + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; + + addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } + if (addr < (mem_size << 10)) + *(uint16_t *)&ram[addr] = val; +} + + +static uint32_t +mem_read_scatl(uint32_t addr, void *priv) +{ + uint32_t val = 0xffffffff; + scat_t *stat = (scat_t *)priv; + + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; + + return val; +} + + +static void +mem_write_scatl(uint32_t addr, uint32_t val, void *priv) +{ + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; + + addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } + if (addr < (mem_size << 10)) + *(uint32_t *)&ram[addr] = val; } @@ -621,17 +1315,25 @@ scat_init(void) int i; io_sethandler(0x0022, 2, - scat_read,NULL,NULL, scat_write,NULL,NULL, NULL); - - port_92_reset(); - - port_92_add(); + scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_sethandler(0x0092, 1, + scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); for (i = 0; i < 256; i++) scat_regs[i] = 0xff; scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - scat_regs[SCAT_VERSION] = 4; + switch(romset) { + case ROM_GW286CT: + case ROM_SPC4216P: + scat_regs[SCAT_VERSION] = 4; + break; + + default: + scat_regs[SCAT_VERSION] = 1; + break; + } + scat_regs[SCAT_CLOCK_CONTROL] = 2; scat_regs[SCAT_PERIPHERAL_CONTROL] = 0x80; scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; @@ -646,37 +1348,45 @@ scat_init(void) scat_regs[SCAT_EMS_CONTROL] = 0; scat_port_92 = 0; - mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + for (i = 0; i < 4; i++) + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_add(&scat_low_mapping[0], 0, 0x40000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); + for(i=2;i<32;i++) + mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, scat_regs[SCAT_VERSION] < 4 ? 0x40000 : 0x60000); - for (i = 0; i < 24; i++) { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + for (i = 0; i < 44; i++) + mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + for (i = 0; i < 8; i++) { + mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); + mem_mapping_disable(&scat_low_ROMCS_mapping[i]); } - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_A000_BFFF_mapping); - for (i = 0; i < 32; i++) { scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_mapping[i]); + mem_mapping_add(&scat_ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); } - for (i=4;i<10;i++) - isram[i] = 0; + for(i=4;i<10;i++) isram[i] = 0; - /* TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. - Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. */ - for (i = 12; i < 16; i++) { + for (i = (scat_regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) { mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL); + mem_mapping_enable(&scat_high_mapping[i]); } - for (i = 0; i < 6; i++) - mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + for(i=0;i<6;i++) + mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); - scat_set_xms_bound(0); - scat_shadow_state_update(); + external_is_RAS = (scat_regs[SCAT_VERSION] > 3) || (((mem_size & ~2047) >> 11) + ((mem_size & 1536) >> 9) + ((mem_size & 511) >> 7)) > 4; + + set_xms_bound(0); + memmap_state_update(); + shadow_state_update(); } @@ -686,11 +1396,9 @@ scatsx_init(void) int i; io_sethandler(0x0022, 2, - scat_read,NULL,NULL, scat_write,NULL,NULL, NULL); - - port_92_reset(); - - port_92_add(); + scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_sethandler(0x0092, 1, + scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); for (i = 0; i < 256; i++) scat_regs[i] = 0xff; @@ -716,33 +1424,46 @@ scatsx_init(void) scat_regs[SCATSX_CAS_TIMING_FOR_DMA] = 3; scat_port_92 = 0; - mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + for (i = 0; i < 4; i++) + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_add(&scat_low_mapping[0], 0, 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); + for(i=2;i<32;i++) + mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, 0x40000); - for (i = 16; i < 24; i++) { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + for (i = 16; i < 44; i++) { + mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + for (i = 0; i < 8; i++) { + mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); + mem_mapping_disable(&scat_low_ROMCS_mapping[i]); } - - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_A000_BFFF_mapping); for (i = 24; i < 32; i++) { scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + 28) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_mapping[i]); + mem_mapping_add(&scat_ems_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + 28) << 14), 0, &scat_stat[i]); + mem_mapping_disable(&scat_ems_mapping[i]); } - /* TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. - Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. */ - for (i = 12; i < 16; i++) + for (i = 0; i < 16; i++) { mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL); + mem_mapping_enable(&scat_high_mapping[i]); + } - for (i = 0; i < 6; i++) - mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + for(i=0;i<6;i++) + mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); - scat_set_xms_bound(0); - scat_shadow_state_update(); + external_is_RAS = scatsx_external_is_RAS[mem_size >> 9]; + + set_xms_bound(0); + memmap_state_update(); + shadow_state_update(); } @@ -750,7 +1471,6 @@ void machine_at_scat_init(const machine_t *model, void *arg) { machine_at_init(model, arg); - device_add(&fdc_at_device); scat_init(); @@ -763,7 +1483,6 @@ machine_at_scatsx_init(const machine_t *model, void *arg) machine_at_common_init(model, arg); device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); scatsx_init(); diff --git a/src/machines/machine.h b/src/machines/machine.h index 81982ef..0429be0 100644 --- a/src/machines/machine.h +++ b/src/machines/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.20 2018/04/25 + * Version: @(#)machine.h 1.0.21 2018/06/14 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -58,6 +58,7 @@ enum { ROM_IBMPC = 0, /* 301 keyboard error, 131 cassette (!!!) error */ ROM_AMIXT, /* XT Clone with AMI BIOS */ + ROM_AWDXT, /* XT Clone with Award BIOS */ ROM_DTKXT, ROM_IBMXT, /* 301 keyboard error */ ROM_GENXT, /* 'Generic XT BIOS' */ diff --git a/src/machines/machine_table.c b/src/machines/machine_table.c index 52b2d20..0833688 100644 --- a/src/machines/machine_table.c +++ b/src/machines/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.22 2018/05/04 + * Version: @(#)machine_table.c 1.0.23 2018/06/14 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -59,6 +59,7 @@ const machine_t machines[] = { { "[8088] IBM XT", ROM_IBMXT, "ibm_xt", L"ibm/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, &m_xt_device, NULL }, { "[8088] OpenXT Generic Clone", ROM_GENXT, "open_xt", L"generic/open_xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, &m_xt_device, NULL }, { "[8088] AMI XT clone", ROM_AMIXT, "ami_xt", L"generic/ami/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, &m_xt_device, NULL }, + { "[8088] Award XT clone", ROM_AWDXT, "awd_xt", L"generic/award/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, &m_xt_device, NULL }, { "[8088] Compaq Portable", ROM_PORTABLE, "compaq_portable", L"compaq/portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL, NULL }, { "[8088] DTK XT clone", ROM_DTKXT, "dtk_xt", L"dtk/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, &m_xt_device, NULL }, { "[8088] Juko XT clone", ROM_JUKOPC, "juko_pc", L"juko/pc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL }, diff --git a/src/pc.c b/src/pc.c index b579c1f..6c774c6 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.46 2018/05/26 + * Version: @(#)pc.c 1.0.47 2018/06/10 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -89,6 +89,9 @@ #include "plat.h" +#define PCLOG_BUFF_SIZE 8192 /* has to be big enough!! */ + + /* Commandline options. */ int dump_on_exit = 0; /* (O) dump regs on exit */ int do_dump_config = 0; /* (O) dump config on load */ @@ -201,14 +204,18 @@ int64_t main_time; * To avoid excessively-large logfiles because some * module repeatedly logs, we keep track of what is * being logged, and catch repeating entries. + * + * Note: we need fairly large buffers here, to allow + * for the network code dumping packet content + * with this. */ void pclog_ex(const char *fmt, va_list ap) { #ifndef RELEASE_BUILD - static char buff[1024]; + static char buff[PCLOG_BUFF_SIZE]; static int seen = 0; - char temp[1024]; + char temp[PCLOG_BUFF_SIZE]; if (stdlog == NULL) { if (log_path[0] != L'\0') { @@ -306,9 +313,7 @@ fatal(const char *fmt, ...) void pc_version(const char *platform) { -#if defined(BUILD) || defined(COMMIT) || defined(UPSTREAM) || defined(_MSC_VER) char temp[128]; -#endif sprintf(emu_title, "%s for %s", EMU_NAME, platform); @@ -319,10 +324,16 @@ pc_version(const char *platform) #endif strcpy(emu_fullversion, emu_version); -#ifdef _MSC_VER - sprintf(temp, " [VC%d]", _MSC_VER); - strcat(emu_fullversion, temp); +#if defined(_MSC_VER) + sprintf(temp, " [VC %d]", _MSC_VER); +#elif defined(__clang_major__) + sprintf(temp, " [Clang %d.%d.%d]", + __clang_major__, __clang_minor__, __clang_patchlevel__); +#elif defined(__GNUC__) + sprintf(temp, " [GCC %d.%d.%d]", + __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); #endif + strcat(emu_fullversion, temp); #ifdef BUILD sprintf(temp, " (Build %d", BUILD); diff --git a/src/rom_load.c b/src/rom_load.c index 8b1e91e..c0f7925 100644 --- a/src/rom_load.c +++ b/src/rom_load.c @@ -17,7 +17,7 @@ * or to use a generic handler, and then pass it a pointer * to a command table. For now, we don't. * - * Version: @(#)rom_load.c 1.0.11 2018/05/27 + * Version: @(#)rom_load.c 1.0.12 2018/06/14 * * Author: Fred N. van Kempen, * @@ -471,5 +471,7 @@ rom_load_bios(romdef_t *r, const wchar_t *fn, int test_only) i, r->total, biosmask); } + if (! i) pclog("ROM: error in script '%ls'\n", script); + return(i); } diff --git a/src/win/lang/Extra-EN.txt b/src/ui/lang/Extra-EN.txt similarity index 100% rename from src/win/lang/Extra-EN.txt rename to src/ui/lang/Extra-EN.txt diff --git a/src/ui/lang/VARCem-BY.str b/src/ui/lang/VARCem-BY.str index c87a87e..dcdc109 100644 Binary files a/src/ui/lang/VARCem-BY.str and b/src/ui/lang/VARCem-BY.str differ diff --git a/src/ui/lang/VARCem-CZ.str b/src/ui/lang/VARCem-CZ.str index fca6bfc..ad3ad8e 100644 Binary files a/src/ui/lang/VARCem-CZ.str and b/src/ui/lang/VARCem-CZ.str differ diff --git a/src/ui/lang/VARCem-DE.str b/src/ui/lang/VARCem-DE.str index dff0878..98f41c8 100644 Binary files a/src/ui/lang/VARCem-DE.str and b/src/ui/lang/VARCem-DE.str differ diff --git a/src/ui/lang/VARCem-DU.str b/src/ui/lang/VARCem-DU.str index 79e2c6c..61ed36a 100644 Binary files a/src/ui/lang/VARCem-DU.str and b/src/ui/lang/VARCem-DU.str differ diff --git a/src/ui/lang/VARCem-ES.str b/src/ui/lang/VARCem-ES.str index b3a7bd4..85830a5 100644 Binary files a/src/ui/lang/VARCem-ES.str and b/src/ui/lang/VARCem-ES.str differ diff --git a/src/ui/lang/VARCem-FI.str b/src/ui/lang/VARCem-FI.str index 328edb2..5d24658 100644 Binary files a/src/ui/lang/VARCem-FI.str and b/src/ui/lang/VARCem-FI.str differ diff --git a/src/ui/lang/VARCem-FR.str b/src/ui/lang/VARCem-FR.str index 3c5b688..36a4285 100644 Binary files a/src/ui/lang/VARCem-FR.str and b/src/ui/lang/VARCem-FR.str differ diff --git a/src/ui/lang/VARCem-IT.str b/src/ui/lang/VARCem-IT.str index bd5498e..35424f7 100644 Binary files a/src/ui/lang/VARCem-IT.str and b/src/ui/lang/VARCem-IT.str differ diff --git a/src/ui/lang/VARCem-JP.str b/src/ui/lang/VARCem-JP.str index bb24726..a069e72 100644 Binary files a/src/ui/lang/VARCem-JP.str and b/src/ui/lang/VARCem-JP.str differ diff --git a/src/ui/lang/VARCem-KR.str b/src/ui/lang/VARCem-KR.str index 4c557e6..e315997 100644 Binary files a/src/ui/lang/VARCem-KR.str and b/src/ui/lang/VARCem-KR.str differ diff --git a/src/ui/lang/VARCem-KZ.str b/src/ui/lang/VARCem-KZ.str index 3e27985..23f7e8e 100644 --- a/src/ui/lang/VARCem-KZ.str +++ b/src/ui/lang/VARCem-KZ.str @@ -13,7 +13,7 @@ * it as the line-by-line base for the translated version, and * update fields as needed. * - * Version: @(#)VARCem-KZ.str 1.0.0 2018/06/10 + * Version: @(#)VARCem-KZ.str 1.0.1 2018/06/10 * * Authors: Arbars Zagadkin, * Fred N. van Kempen, @@ -52,7 +52,7 @@ */ /* Do not translate! */ -#define TAG_VERSION 1,0,0 +#define TAG_VERSION 1,0,1 #define TAG_AUTHOR "Arbars Zagadkin" #define TAG_EMAIL "arbars.zagadkin@mail.ru" @@ -128,9 +128,9 @@ /* UI: dialog: About (3200.) */ #define STR_ABOUT "VARCem туралы..." #define STR_3201 "Авторлар:" -#define STR_3202 "Fred N. van Kempen, Miran Grca, Sarah Walker, TheCollector1995, reenigne, John Elliott, greatpsycho, және тағы басқа." -#define STR_3203 "Бағдарлама 86Box, PCem, MAME, DOSbox және Qemu алғашқы жазбахабардан негізделген" -#define STR_3204 "BSD 3 және GNU General Public License (2-ші немесе одан жоғары ңұсқасы) лицензиялар бойынша жарияланған. Мәліметтер LICENSE.txt файлда қараңыз" +#define STR_3202 "Fred N. van Kempen, Miran Grca, Sarah Walker және тағы басқа.\nБағдарлама 86Box, PCem, MAME, DOSbox және Qemu алғашқы жазбахабардан негізделген" +#define STR_3203 "BSD 3 және GNU General Public License (2-ші немесе одан жоғары ңұсқасы) лицензиялар бойынша жарияланған." +#define STR_3204 "Мәліметтер LICENSE.txt файлда қараңыз" #define STR_LOCALIZE "Аударма" #define STR_3211 "Анғылыштан басқа тілдерге аудармалар авторлар:" @@ -347,7 +347,7 @@ #define STR_4020 "Рендерер" /* Menu: View > Window Scale Factor */ -#define STR_4030 Терезенің ауқығы" +#define STR_4030 "Терезенің ауқығы" #define STR_4031 "0.5x" #define STR_4032 "1x" #define STR_4033 "1.5x" diff --git a/src/ui/lang/VARCem-LT.str b/src/ui/lang/VARCem-LT.str index 3d272bb..87c0367 100644 Binary files a/src/ui/lang/VARCem-LT.str and b/src/ui/lang/VARCem-LT.str differ diff --git a/src/ui/lang/VARCem-RU.str b/src/ui/lang/VARCem-RU.str index 670efa9..8fe8911 100644 Binary files a/src/ui/lang/VARCem-RU.str and b/src/ui/lang/VARCem-RU.str differ diff --git a/src/ui/lang/VARCem-SL.str b/src/ui/lang/VARCem-SL.str index 2c4474a..512e793 100644 Binary files a/src/ui/lang/VARCem-SL.str and b/src/ui/lang/VARCem-SL.str differ diff --git a/src/ui/lang/VARCem-UA.str b/src/ui/lang/VARCem-UA.str index 1d3c4be..f6743e1 100644 Binary files a/src/ui/lang/VARCem-UA.str and b/src/ui/lang/VARCem-UA.str differ diff --git a/src/ui/lang/VARCem.lang b/src/ui/lang/VARCem.lang new file mode 100644 index 0000000..e9b578e --- /dev/null +++ b/src/ui/lang/VARCem.lang @@ -0,0 +1,61 @@ +# +# VARCem Virtual ARchaeological Computer EMulator. +# An emulator of (mostly) x86-based PC systems and devices, +# using the ISA,EISA,VLB,MCA and PCI system buses, roughly +# spanning the era between 1981 and 1995. +# +# This file is part of the VARCem Project. +# +# Supported Languages database. +# +# Version: @(#)VARCem.lang 1.0.1 2018/06/14 +# +# Author: Fred N. van Kempen, +# +# Copyright 2018 Fred N. van Kempen. +# +# Redistribution and use in source and binary forms, with +# or without modification, are permitted provided that the +# following conditions are met: +# +# 1. Redistributions of source code must retain the entire +# above notice, this list of conditions and the following +# disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the +# following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names +# of its contributors may be used to endorse or promote +# products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +BY,0423,LANG_BELARUSIAN,SUBLANG_BELARUSIAN_BELARUS +CZ,0405,LANG_CZECH,SUBLANG_CZECH_CZECH_REPUBLIC +DE,0407,LANG_GERMAN,SUBLANG_GERMAN +DU,0413,LANG_DUTCH,SUBLANG_DUTCH +ES,040a,LANG_SPANISH,SUBLANG_SPANISH +FI,040b,LANG_FINNISH,SUBLANG_FINNISH_FINLAND +FR,040c,LANG_FRENCH,SUBLANG_FRENCH +IT,0410,LANG_ITALIAN,SUBLANG_ITALIAN +JP,0411,LANG_JAPANESE,SUBLANG_JAPANESE_JAPAN +KR,0412,LANG_KOREAN,SUBLANG_KOREAN +KZ,043f,LANG_KAZAK,SUBLANG_KAZAK_KAZAKHSTAN +LT,0427,LANG_LITHUANIAN,SUBLANG_LITHUANIAN_LITHUANIA +RU,0419,LANG_RUSSIAN,SUBLANG_RUSSIAN_RUSSIA +SL,0424,LANG_SLOVENIAN,SUBLANG_SLOVENIAN_SLOVENIA +UA,0422,LANG_UKRANIAN,SUBLANG_UKTRANIAN_UKRAINE diff --git a/src/win/VARCem.rc b/src/win/VARCem.rc index bfc542f..2b61dd4 100644 --- a/src/win/VARCem.rc +++ b/src/win/VARCem.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)VARCem.rc 1.0.32 2018/06/02 + * Version: @(#)VARCem.rc 1.0.33 2018/06/16 * * Author: Fred N. van Kempen, * @@ -245,6 +245,6 @@ VS_VERSION_INFO VERSIONINFO END BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x409, 1200 + VALUE "Translation", 0x409, 65001 END END diff --git a/src/win/mingw/include/zconf.h b/src/win/mingw/include/zconf.h deleted file mode 100644 index 03a9431..0000000 --- a/src/win/mingw/include/zconf.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/src/win/mingw/include/zlib.h b/src/win/mingw/include/zlib.h deleted file mode 100644 index 0228179..0000000 --- a/src/win/mingw/include/zlib.h +++ /dev/null @@ -1,1357 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/src/win/msvc/vc14/VARCem.sln b/src/win/msvc/vc14/VARCem.sln index abf3d6f..3c9f684 100644 --- a/src/win/msvc/vc14/VARCem.sln +++ b/src/win/msvc/vc14/VARCem.sln @@ -13,8 +13,8 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x64.ActiveCfg = Debug|Win32 - {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x64.Build.0 = Debug|Win32 + {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x64.ActiveCfg = Debug|x64 + {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x64.Build.0 = Debug|x64 {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x86.ActiveCfg = Debug|Win32 {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Debug|x86.Build.0 = Debug|Win32 {6E445F28-CA8F-430F-8CCF-C59C53516AC5}.Release|x64.ActiveCfg = Release|x64 diff --git a/src/win/msvc/vc14/VARCem.vcxproj b/src/win/msvc/vc14/VARCem.vcxproj index 2f3cb36..c334665 100644 --- a/src/win/msvc/vc14/VARCem.vcxproj +++ b/src/win/msvc/vc14/VARCem.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -19,7 +19,7 @@ - + @@ -43,256 +43,260 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -307,16 +311,18 @@ - + + + - + @@ -562,18 +568,54 @@ - - + + + + + + + + + + + + - + + true + true + _MSC_VER + _MSC_VER + + + + + Document + Generating Manifest file... + Generating Manifest file... + Generating Manifest file... + Generating Manifest file... + VARCem.manifest + VARCem.manifest + VARCem.manifest + VARCem.manifest + VARCem.rc + VARCem.rc + VARCem.rc + VARCem.rc + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + - 15.0 + 14.0 {6E445F28-CA8F-430F-8CCF-C59C53516AC5} Win32Proj VARCem - 10.0.10586.0 + 8.1 @@ -627,20 +669,22 @@ true $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + false true - false $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) + false false $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + false false - false $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) + false @@ -649,12 +693,11 @@ Disabled true WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true Windows Debug - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) 5.01 @@ -669,12 +712,11 @@ Disabled true _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true Windows Debug - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) 5.01 @@ -690,14 +732,13 @@ true true WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true Windows true true Debug - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) 5.01 @@ -714,14 +755,13 @@ true true NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true Windows true true Debug - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) 5.01 diff --git a/src/win/msvc/vc14/VARCem.vcxproj.filters b/src/win/msvc/vc14/VARCem.vcxproj.filters index 22bc89c..cc44658 100644 --- a/src/win/msvc/vc14/VARCem.vcxproj.filters +++ b/src/win/msvc/vc14/VARCem.vcxproj.filters @@ -1,46 +1,15 @@ - + - - - - - - - - - - - - - - - - - - - - - cdrom - - - cdrom - - - cdrom - - - cdrom - cpu @@ -92,681 +61,6 @@ cpu - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - disk - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy\lzf - - - floppy\lzf - - - input\game - - - input\game - - - input\game - - - input\game - - - input\game - - - input - - - input - - - input - - - input - - - input - - - input - - - input - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - machine - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network - - - network - - - network - - - network - - - ports - - - ports - - - ports - - - ports - - - ports - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - sio - - - sio - - - sio - - - sio - - - sio - - - sio - - - sio - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\munt\sha1 - - - sound\munt\c_interface - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - ui - - - ui - - - ui - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - win @@ -809,9 +103,6 @@ win - - win - win @@ -830,46 +121,779 @@ win + + + ui + + + ui + + + devices\cdrom + + + devices\cdrom + + + devices\cdrom + + + devices\cdrom + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\floppy\lzf + + + devices\floppy\lzf + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\input\game + + + devices\input\game + + + devices\input\game + + + devices\input\game + + + devices\input\game + + + devices\input + + + devices\input + + + devices\input + + + devices\input + + + devices\input + + + devices\input + + + devices\input + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network + + + devices\network + + + devices\network + + + devices\network + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\sio + + + devices\sio + + + devices\sio + + + devices\sio + + + devices\sio + + + devices\sio + + + devices\sio + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\munt\c_interface + + + devices\sound\munt\sha1 + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + machines + + + devices\video + + + devices\misc + + + ui + + + + devices\network\slirp + + + win + + + win + + + ui + + + win + - - - - - - - - - - - - - - - - - - cdrom - - - cdrom - - - cdrom - - - cdrom - cpu @@ -1071,441 +1095,6 @@ cpu - - disk - - - disk - - - disk - - - disk - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy - - - floppy\lzf - - - floppy\lzf - - - floppy\lzf - - - floppy\lzf - - - input - - - input - - - input\game - - - machine - - - machine - - - machine - - - machine - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network\slirp - - - network - - - network - - - network - - - ports - - - ports - - - ports - - - ports - - - ports - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - scsi - - - sio - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\resid-fp - - - sound\munt\sha1 - - - sound\munt\c_interface - - - sound\munt\c_interface - - - sound\munt\c_interface - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound\munt - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - sound - - - ui - - - ui - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - - - video - win @@ -1515,76 +1104,611 @@ win - + + + ui + + + ui + + + devices\cdrom + + + devices\cdrom + + + devices\cdrom + + + devices\cdrom + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\disk + + + devices\floppy\lzf + + + devices\floppy\lzf + + + devices\floppy\lzf + + + devices\floppy\lzf + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\floppy + + + devices\input\game + + + devices\input + + + devices\input + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network\slirp + + + devices\network + + + devices\network + + + devices\network + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\ports + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\scsi + + + devices\sio + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\resid-fp + + + devices\sound\munt\c_interface + + + devices\sound\munt\c_interface + + + devices\sound\munt\c_interface + + + devices\sound\munt\sha1 + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\sound\munt + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\system + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + devices\video + + + machines + + + machines + + + machines + + + machines + + + devices\misc + + win - + + win + + + win + + + win + + + win + + + win + + + win + + + win + + + win + + + win + + + win + + win - - {33d139d2-8501-4ec5-adf5-30695fd66b58} - {7a5514af-a83b-483a-bfac-af1e20215c22} - - {0eb40b0a-0704-4966-b094-dc23e7fb1224} - - - {a9a86e4f-b4eb-4687-a979-f97b394db706} - - - {98d7b877-02b8-4c6b-b2b6-d2cc49f357bc} - - - {923338ef-338a-4592-9839-9f8587d93c52} - - - {fc7fc92b-b4da-4f3c-a5c7-4d2548b60fb2} - - - {a99de26d-e4fd-4223-952c-21f1657a20e7} - - - {7cae45b9-af45-4f82-9c53-a4e3094ddee4} - - - {c0afa9df-08d3-40a6-a4d4-88fb97816009} - - - {b9d0388f-b14d-4448-85fe-7179fff3f77f} - - - {515f18e5-5eab-42f6-8364-37f02bc4f964} - - - {4fc4a59c-bb7c-45d7-a467-a06198e71472} - - - {2617b8d7-3afc-4f23-a0c8-936dab6c38b6} - - - {b28a24be-02cf-4896-9c96-aee25851df13} - - - {74dd2459-6b2f-4123-bddd-37f561ea710d} - - - {b8b30a24-da56-40f2-9a15-9c90ec2a98ed} - - - {144b7265-aa9e-453b-9855-78cd74ef9b76} + + {cb655d08-c712-4197-9eb8-2f5b7f49eed1} {7cec753e-1e2c-4ebd-ba5b-e728767c949f} - + + {e97ddf22-9ad1-46da-bc17-bd998507adf8} + + + {33d139d2-8501-4ec5-adf5-30695fd66b58} + + + {0eb40b0a-0704-4966-b094-dc23e7fb1224} + + + {a9a86e4f-b4eb-4687-a979-f97b394db706} + + + {98d7b877-02b8-4c6b-b2b6-d2cc49f357bc} + + + {923338ef-338a-4592-9839-9f8587d93c52} + + + {fc7fc92b-b4da-4f3c-a5c7-4d2548b60fb2} + + + {7cae45b9-af45-4f82-9c53-a4e3094ddee4} + + + {c0afa9df-08d3-40a6-a4d4-88fb97816009} + + + {b9d0388f-b14d-4448-85fe-7179fff3f77f} + + + {515f18e5-5eab-42f6-8364-37f02bc4f964} + + + {4fc4a59c-bb7c-45d7-a467-a06198e71472} + + + {2617b8d7-3afc-4f23-a0c8-936dab6c38b6} + + + {b28a24be-02cf-4896-9c96-aee25851df13} + + + {b8b30a24-da56-40f2-9a15-9c90ec2a98ed} + + + {144b7265-aa9e-453b-9855-78cd74ef9b76} + + + {309c083e-3028-4e46-a758-a8afeb95e914} + + + {4b343ed5-4818-4b62-beac-fcbc4185383f} + + {99b35c64-342c-4f15-89b0-47c15f8db344} - - {cb655d08-c712-4197-9eb8-2f5b7f49eed1} + + {c21f8b49-308c-4e25-b69d-b03c1e24617a} + + + {51f1c4aa-4a2a-4639-bcbc-2075ffaf3e27} @@ -1592,4 +1716,9 @@ win - + + + win + + + \ No newline at end of file diff --git a/src/win/msvc/vc14/VARCem.vcxproj.user b/src/win/msvc/vc14/VARCem.vcxproj.user index be25078..a1392fb 100644 --- a/src/win/msvc/vc14/VARCem.vcxproj.user +++ b/src/win/msvc/vc14/VARCem.vcxproj.user @@ -1,4 +1,19 @@  - - - \ No newline at end of file + + + -L varcem.log + WindowsLocalDebugger + + + -L varcem.log + WindowsLocalDebugger + + + -L varcem.log + WindowsLocalDebugger + + + -L varcem.log + WindowsLocalDebugger + + diff --git a/src/win/msvc/vc14/global.props b/src/win/msvc/vc14/global.props index d29a058..f19a0ec 100644 --- a/src/win/msvc/vc14/global.props +++ b/src/win/msvc/vc14/global.props @@ -3,11 +3,11 @@ - $(ProjectDir)\..\Include;$(ProjectDir)\..\..\mingw\include;$(ProjectDir)\..\..\mingw\include\pcap;$(IncludePath) + $(ProjectDir)\..\Include;$(ProjectDir)\..\..\mingw\include;$(ProjectDir)\..\..\mingw\include\pcap;P:\SDL\include\msvc;$(IncludePath) - _USE_MATH_DEFINES;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;USE_DYNAREC;USE_OPENAL + _USE_MATH_DEFINES;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;USE_DYNAREC;USE_OPENAL;USE_SDL diff --git a/src/win/win_ddraw.cpp b/src/win/win_ddraw.cpp index 0ce10b2..80d399b 100644 --- a/src/win/win_ddraw.cpp +++ b/src/win/win_ddraw.cpp @@ -8,15 +8,12 @@ * * Rendering module for Microsoft DirectDraw 9. * - * NOTES: This code should be re-merged into a single init() with a - * 'fullscreen' argument, indicating FS mode is requested. - * * If configured with USE_LIBPNG, we try to load the external * PNG library and use that if found. Otherwise, we fall back * the original mode, which uses the Windows/DDraw built-in BMP * format. * - * Version: @(#)win_ddraw.cpp 1.0.13 2018/05/24 + * Version: @(#)win_ddraw.cpp 1.0.15 2018/06/11 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -91,6 +88,8 @@ png_structp (*PNG_create_write_struct)(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn); +void (*PNG_destroy_write_struct)(png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr); png_infop (*PNG_create_info_struct)(png_const_structrp png_ptr); void (*PNG_init_io)(png_structrp png_ptr, png_FILE_p fp); void (*PNG_set_IHDR)(png_const_structrp png_ptr, @@ -112,6 +111,7 @@ void (*PNG_write_end)(png_structrp png_ptr, static const dllimp_t png_imports[] = { { "png_create_write_struct", &PNG_create_write_struct }, + { "png_destroy_write_struct", &PNG_destroy_write_struct }, { "png_create_info_struct", &PNG_create_info_struct }, { "png_init_io", &PNG_init_io }, { "png_set_IHDR", &PNG_set_IHDR }, @@ -211,288 +211,6 @@ GetError(HRESULT hr) } -static HBITMAP -CopySurface(IDirectDrawSurface4 *pDDSurface) -{ - HBITMAP hbmp, hbmprev; - DDSURFACEDESC2 ddsd; - HDC hdc, hmemdc; - - pDDSurface->GetDC(&hdc); - hmemdc = CreateCompatibleDC(hdc); - ZeroMemory(&ddsd, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - pDDSurface->GetSurfaceDesc(&ddsd); - hbmp = CreateCompatibleBitmap(hdc, xs, ys); - hbmprev = (HBITMAP)SelectObject(hmemdc, hbmp); - BitBlt(hmemdc, 0, 0, xs, ys, hdc, 0, 0, SRCCOPY); - SelectObject(hmemdc, hbmprev); - DeleteDC(hmemdc); - pDDSurface->ReleaseDC(hdc); - - return(hbmp); -} - - -static void -DoubleLines(uint8_t *dst, uint8_t *src) -{ - int i = 0; - - for (i = 0; i < ys; i++) { - memcpy(dst + (i * xs * 8), src + (i * xs * 4), xs * 4); - memcpy(dst + ((i * xs * 8) + (xs * 4)), src + (i * xs * 4), xs * 4); - } -} - - -#ifdef USE_LIBPNG -static void -bgra_to_rgb(png_bytep *b_rgb, uint8_t *bgra, int width, int height) -{ - int i, j; - uint8_t *r, *b; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - r = &b_rgb[(height - 1) - i][j * 3]; - b = &bgra[((i * width) + j) * 4]; - r[0] = b[2]; - r[1] = b[1]; - r[2] = b[0]; - } - } -} - - -/* Not strictly needed, but hey.. */ -static void -png_error_handler(png_structp arg, const char *str) -{ - pclog("DDraw: PNG error '%08lx'\n", str); -} - - -/* Not strictly needed, but hey.. */ -static void -png_warning_handler(png_structp arg, const char *str) -{ - pclog("DDraw: PNG warning '%08lx'\n", str); -} - - -static void -SavePNG(const wchar_t *fn, HBITMAP hBitmap) -{ - wchar_t temp[512]; - BITMAPINFO bmpInfo; - HDC hdc; - LPVOID pBuf = NULL; - LPVOID pBuf2 = NULL; - png_bytep *b_rgb = NULL; - png_infop info_ptr; - png_structp png_ptr; - FILE *fp; - int i; - - /* Create file. */ - fp = plat_fopen(fn, L"wb"); - if (fp == NULL) { - pclog("[SavePNG] File %ls could not be opened for writing!\n", fn); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - /* Initialize PNG stuff. */ - png_ptr = PNGFUNC(create_write_struct)(PNG_LIBPNG_VER_STRING, (char *)1234, - png_error_handler, png_warning_handler); - if (png_ptr == NULL) { - (void)fclose(fp); - pclog("[SavePNG] png_create_write_struct failed!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - info_ptr = PNGFUNC(create_info_struct)(png_ptr); - if (info_ptr == NULL) { -// PNGFUNC(destroy_write_struct)(&png_ptr, NULL, NULL); - (void)fclose(fp); - pclog("[SavePNG] png_create_info_struct failed!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - PNGFUNC(init_io)(png_ptr, fp); - - hdc = GetDC(NULL); - - ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); - bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - - GetDIBits(hdc, hBitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); - if (bmpInfo.bmiHeader.biSizeImage <= 0) - bmpInfo.bmiHeader.biSizeImage = - bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; - - if ((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) { -// PNGFUNC(destroy_write_struct)(&png_ptr, &info_ptr, NULL); - (void)fclose(fp); - pclog("[SavePNG] Unable to allocate bitmap memory!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - if (ys2 <= 250) { - bmpInfo.bmiHeader.biSizeImage <<= 1; - - if ((pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) { -// PNGFUNC(destroy_write_struct)(&png_ptr, &info_ptr, NULL); - (void)fclose(fp); - free(pBuf); - pclog("[SavePNG] Unable to allocate secondary bitmap memory!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - bmpInfo.bmiHeader.biHeight <<= 1; - } -#if 1 - pclog("save png w=%i h=%i\n", - bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight); -#endif - - bmpInfo.bmiHeader.biCompression = BI_RGB; - - GetDIBits(hdc, hBitmap, 0, - bmpInfo.bmiHeader.biHeight, pBuf, &bmpInfo, DIB_RGB_COLORS); - - PNGFUNC(set_IHDR)(png_ptr, info_ptr, - bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - b_rgb = (png_bytep *)malloc(sizeof(png_bytep)*bmpInfo.bmiHeader.biHeight); - if (b_rgb == NULL) { -// PNGFUNC(destroy_write_struct)(&png_ptr, NULL, NULL); - (void)fclose(fp); - free(pBuf); - free(pBuf2); - pclog("[SavePNG] Unable to allocate RGB bitmap memory!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - for (i = 0; i < bmpInfo.bmiHeader.biHeight; i++) - b_rgb[i] = (png_byte *)malloc(PNGFUNC(get_rowbytes)(png_ptr, info_ptr)); - - if (pBuf2) { - DoubleLines((uint8_t *)pBuf2, (uint8_t *)pBuf); - bgra_to_rgb(b_rgb, (uint8_t *)pBuf2, - bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight); - } else - bgra_to_rgb(b_rgb, (uint8_t *)pBuf, - bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight); - - PNGFUNC(write_info)(png_ptr, info_ptr); - - PNGFUNC(write_image)(png_ptr, b_rgb); - - PNGFUNC(write_end)(png_ptr, NULL); - - /* Clean up. */ - if (fp != NULL) fclose(fp); -// PNGFUNC(destroy_write_struct)(&png_ptr, &info_ptr, NULL); - if (hdc) ReleaseDC(NULL, hdc); - - if (b_rgb != NULL) { - for (i = 0; i < bmpInfo.bmiHeader.biHeight; i++) - free(b_rgb[i]); - free(b_rgb); - } - - if (pBuf != NULL) free(pBuf); - if (pBuf2 != NULL) free(pBuf2); -} -#endif - - -static void -SaveBMP(const wchar_t *fn, HBITMAP hBitmap) -{ - wchar_t temp[512]; - BITMAPFILEHEADER bmpFileHeader; - BITMAPINFO bmpInfo; - HDC hdc; - FILE *fp = NULL; - LPVOID pBuf = NULL; - LPVOID pBuf2 = NULL; - - hdc = GetDC(NULL); - - ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); - bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - - GetDIBits(hdc, hBitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); - - if (bmpInfo.bmiHeader.biSizeImage <= 0) - bmpInfo.bmiHeader.biSizeImage = - bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; - - if ((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) { - pclog("[SaveBMP] Unable to allocate bitmap memory!\n"); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - if (ys2 <= 250) - pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2); - - bmpInfo.bmiHeader.biCompression = BI_RGB; - - GetDIBits(hdc, hBitmap, 0, bmpInfo.bmiHeader.biHeight, - pBuf, &bmpInfo, DIB_RGB_COLORS); - - if ((fp = plat_fopen(fn, L"wb")) == NULL) { - pclog("[SaveBMP] File %ls could not be opened for writing!\n", fn); - _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); - ui_msgbox(MBX_ERROR, temp); - return; - } - - bmpFileHeader.bfReserved1 = 0; - bmpFileHeader.bfReserved2 = 0; - if (pBuf2) { - bmpInfo.bmiHeader.biSizeImage <<= 1; - bmpInfo.bmiHeader.biHeight <<= 1; - } - bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; - bmpFileHeader.bfType=0x4D42; - bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); - - (void)fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); - (void)fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); - if (pBuf2) { - DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf); - (void)fwrite(pBuf2,bmpInfo.bmiHeader.biSizeImage,1,fp); - } else { - (void)fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); - } - - /* Clean up. */ - if (fp != NULL) fclose(fp); - if (hdc != NULL) ReleaseDC(NULL, hdc); - if (pBuf2 != NULL) free(pBuf2); - if (pBuf != NULL) free(pBuf); -} - - static void ddraw_fs_size_default(RECT w_rect, RECT *r_dest) { @@ -735,23 +453,23 @@ ddraw_close(void) video_setblit(NULL); - if (lpdds_back2) { + if (lpdds_back2 != NULL) { lpdds_back2->Release(); lpdds_back2 = NULL; } - if (lpdds_back) { + if (lpdds_back != NULL) { lpdds_back->Release(); lpdds_back = NULL; } - if (lpdds_pri) { + if (lpdds_pri != NULL) { lpdds_pri->Release(); lpdds_pri = NULL; } - if (lpdd_clipper) { + if (lpdd_clipper != NULL) { lpdd_clipper->Release(); lpdd_clipper = NULL; } - if (lpdd4) { + if (lpdd4 != NULL) { lpdd4->Release(); lpdd4 = NULL; } @@ -766,66 +484,6 @@ ddraw_close(void) } -#if 0 -int -ddraw_init_fs(HWND h) -{ - ddraw_w = GetSystemMetrics(SM_CXSCREEN); - ddraw_h = GetSystemMetrics(SM_CYSCREEN); - - cgapal_rebuild(); - - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) return 0; - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) return 0; - - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_close); - - if (FAILED(lpdd4->SetCooperativeLevel(h, - DDSCL_SETFOCUSWINDOW | \ - DDSCL_CREATEDEVICEWINDOW | \ - DDSCL_EXCLUSIVE | \ - DDSCL_FULLSCREEN | \ - DDSCL_ALLOWREBOOT))) return 0; - - if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.dwBackBufferCount = 1; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) return 0; - - ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; - if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2))) return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) return 0; - } - - ddraw_hwnd = h; - - video_setblit(ddraw_blit_fs); - - return(1); -} -#endif - - static int ddraw_init(int fs) { @@ -844,7 +502,6 @@ ddraw_init(int fs) pclog("DDRAW: cannot create an instance (%s)\n", GetError(hr)); return(0); } - hr = lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4); if (FAILED(hr)) { pclog("DDRAW: no interfaces found (%s)\n", GetError(hr)); @@ -868,50 +525,107 @@ ddraw_init(int fs) return(0); } - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + if (fs) { + ddraw_w = GetSystemMetrics(SM_CXSCREEN); + ddraw_h = GetSystemMetrics(SM_CYSCREEN); + hr = lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0, 0); + if (FAILED(hr)) { + pclog("DDRAW: SetDisplayMode failed (%s)\n", GetError(hr)); + return(0); + } + } + memset(&ddsd, 0x00, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) return(0); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); + if (fs) { + ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX | DDSCAPS_FLIP); + ddsd.dwBackBufferCount = 1; + } + hr = lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL); + if (FAILED(hr)) { + pclog("DDRAW: CreateSurface failed (%s)\n", GetError(hr)); + return(0); } - memset(&ddsd, 0, sizeof(ddsd)); + if (fs) { + memset(&ddsd, 0x00, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; + hr = lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2); + if (FAILED(hr)) { + pclog("DDRAW: GetAttachedSurface failed (%s)\n", GetError(hr)); + return(0); + } + } + + memset(&ddsd, 0x00, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; + ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) { + hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); + if (FAILED(hr)) { ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; + ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) - fatal("CreateSurface back failed\n"); + hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); + if (FAILED(hr)) { + pclog("DDRAW: CreateSurface(back) failed (%s)\n", GetError(hr)); + return(0); + } } - if (FAILED(lpdd4->CreateClipper(0, &lpdd_clipper, NULL))) return(0); + if (! fs) { + memset(&ddsd, 0x00, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + hr = lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL); + if (FAILED(hr)) { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + hr = lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL); + if (FAILED(hr)) { + pclog("DDRAW: CreateSurface(back2) failed (%s)\n", GetError(hr)); + return(0); + } + } - if (FAILED(lpdd_clipper->SetHWnd(0, h))) return(0); + hr = lpdd4->CreateClipper(0, &lpdd_clipper, NULL); + if (FAILED(hr)) { + pclog("DDRAW: CreateClipper failed (%s)\n", GetError(hr)); + return(0); + } - if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) return(0); + hr = lpdd_clipper->SetHWnd(0, h); + if (FAILED(hr)) { + pclog("DDRAW: SetHWnd failed (%s)\n", GetError(hr)); + return(0); + } + + hr = lpdds_pri->SetClipper(lpdd_clipper); + if (FAILED(hr)) { + pclog("DDRAW: SetClipper failed (%s)\n", GetError(hr)); + return(0); + } + } ddraw_hwnd = h; - video_setblit(ddraw_blit); + if (fs) + video_setblit(ddraw_blit_fs); + else + video_setblit(ddraw_blit); #ifdef USE_LIBPNG # if USE_LIBPNG == 2 @@ -929,11 +643,197 @@ ddraw_init(int fs) } +#ifdef USE_LIBPNG +static void +bgra_to_rgb(png_bytep *b_rgb, uint8_t *bgra, int width, int height) +{ + int h, w; + uint8_t *r, *b; + + for (h = 0; h < height; h++) { + for (w = 0; w < width; w++) { + /* Get pointer to pixel in bitmap data. */ + b = &bgra[((h * width) + w) * 4]; + + /* Get pointer to png row data. */ + r = &b_rgb[(height - 1) - h][w * 3]; + + /* Copy the pixel data. */ + r[0] = b[2]; + r[1] = b[1]; + r[2] = b[0]; + } + } +} + + +static void +error_handler(png_structp arg, const char *str) +{ + pclog("PNG: stream 0x%08lx error '%s'\n", arg, str); +} + + +static void +warning_handler(png_structp arg, const char *str) +{ + pclog("PNG: stream 0x%08lx warning '%s'\n", arg, str); +} + + +static int +SavePNG(const wchar_t *fn, BITMAPINFO *bmi, uint8_t *pixels) +{ + png_structp png = NULL; + png_infop info = NULL; + uint8_t *r, *b; + png_bytep row; + FILE *fp; + int h, w; + + /* Create the image file. */ + fp = plat_fopen(fn, L"wb"); + if (fp == NULL) { + pclog("[SavePNG] File %ls could not be opened for writing!\n", fn); +error: + if (png != NULL) + PNGFUNC(destroy_write_struct)(&png, &info); + if (fp != NULL) + (void)fclose(fp); + return(0); + } + + /* Initialize PNG stuff. */ + png = PNGFUNC(create_write_struct)(PNG_LIBPNG_VER_STRING, NULL, + error_handler, warning_handler); + if (png == NULL) { + pclog("[SavePNG] create_write_struct failed!\n"); + goto error; + } + + info = PNGFUNC(create_info_struct)(png); + if (info == NULL) { + pclog("[SavePNG] create_info_struct failed!\n"); + goto error; + } + + PNGFUNC(init_io)(png, fp); + + PNGFUNC(set_IHDR)(png, info, + bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 8, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + +pclog("PNG: write_info\n"); + PNGFUNC(write_info)(png, info); + + /* Create a buffer for one scanline of pixels. */ + row = (png_bytep)malloc(PNGFUNC(get_rowbytes)(png, info)); + + /* Process all scanlines in the image. */ +pclog("PNG: convert\n"); + for (h = 0; h < bmi->bmiHeader.biHeight; h++) { + r = row; + for (w = 0; w < bmi->bmiHeader.biWidth; w++) { + /* Get pointer to pixel in bitmap data. */ + b = &pixels[((h * bmi->bmiHeader.biWidth) + w) * 4]; + + /* Copy the pixel data. */ + r[0] = b[2]; + r[1] = b[1]; + r[2] = b[0]; + + /* Next pixel on scanline. */ + r += 3; + } + + /* Write this row to the file. */ +// png_write_row(png, row); + } + + /* No longer need the row buffer. */ + free(row); + +#if 0 +pclog("PNG: write_end\n"); + PNGFUNC(write_end)(png, NULL); +#endif + +pclog("PNG: destroy\n"); + PNGFUNC(destroy_write_struct)(&png, &info); + + /* Clean up. */ +pclog("PNG: fclose\n"); + (void)fclose(fp); + +pclog("PNG: done!\n"); + return(1); +} +#endif + + +static int +SaveBMP(const wchar_t *fn, BITMAPINFO *bmi, uint8_t *pixels) +{ + BITMAPFILEHEADER bmpHdr; + FILE *fp; + + if ((fp = plat_fopen(fn, L"wb")) == NULL) { + pclog("[SaveBMP] File %ls could not be opened for writing!\n", fn); + return(0); + } + + memset(&bmpHdr, 0x00, sizeof(BITMAPFILEHEADER)); + bmpHdr.bfSize = sizeof(BITMAPFILEHEADER) + \ + sizeof(BITMAPINFOHEADER) + bmi->bmiHeader.biSizeImage; + bmpHdr.bfType = 0x4D42; + bmpHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + + (void)fwrite(&bmpHdr, sizeof(BITMAPFILEHEADER), 1, fp); + (void)fwrite(&bmi->bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp); + (void)fwrite(pixels, bmi->bmiHeader.biSizeImage, 1, fp); + + /* Clean up. */ + (void)fclose(fp); + + return(1); +} + + +static HBITMAP +CopySurface(IDirectDrawSurface4 *pDDSurface) +{ + HBITMAP hBmp, hOldBmp; + DDSURFACEDESC2 ddsd; + HDC hDC, hMemDC; + + pDDSurface->GetDC(&hDC); + hMemDC = CreateCompatibleDC(hDC); + memset(&ddsd, 0x00, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + pDDSurface->GetSurfaceDesc(&ddsd); + hBmp = CreateCompatibleBitmap(hDC, xs, ys); + hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp); + BitBlt(hMemDC, 0, 0, xs, ys, hDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hOldBmp); + DeleteDC(hMemDC); + pDDSurface->ReleaseDC(hDC); + + return(hBmp); +} + + static void ddraw_screenshot(const wchar_t *fn) { + wchar_t path[512]; wchar_t temp[512]; - HBITMAP hbmp; + BITMAPINFO bmi; + uint8_t *pixels; + uint8_t *pix2; + HBITMAP hBmp; + HDC hDC; + int i; #if 0 xs = xsize; @@ -962,24 +862,95 @@ ddraw_screenshot(const wchar_t *fn) ys2 >>= 1; } - hbmp = CopySurface(lpdds_back2); + /* Create a surface copy and store it as a bitmap. */ + hBmp = CopySurface(lpdds_back); + + /* Create a compatible DC. */ + hDC = GetDC(NULL); + + /* Request the size info from the bitmap. */ + memset(&bmi, 0x00, sizeof(BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + GetDIBits(hDC, hBmp, 0, 0, NULL, &bmi, DIB_RGB_COLORS); + if (bmi.bmiHeader.biSizeImage <= 0) { + bmi.bmiHeader.biSizeImage = bmi.bmiHeader.biWidth * abs(bmi.bmiHeader.biHeight) * (bmi.bmiHeader.biBitCount + 7) / 8; + } + + /* Allocate a buffer for the pixel data. */ + if ((pixels = (uint8_t *)malloc(bmi.bmiHeader.biSizeImage)) == NULL) { + pclog("DDraw: unable to allocate bitmap memory!\n"); + _swprintf(temp, get_string(IDS_ERR_SCRSHOT), fn); + ui_msgbox(MBX_ERROR, temp); + ReleaseDC(NULL, hDC); + return; + } + + /* Now get the actual pixel data from the bitmap. */ + bmi.bmiHeader.biCompression = BI_RGB; + GetDIBits(hDC, hBmp, 0, bmi.bmiHeader.biHeight, + pixels, &bmi, DIB_RGB_COLORS); + + /* No longer need the DC. */ + ReleaseDC(NULL, hDC); + + /* + * For some CGA modes (320x200, 640x200 etc) we double-up + * the image height so it looks a little better. We simply + * copy each real scanline. + */ + if (ys <= 250) { + /* Save current buffer. */ + pix2 = pixels; + + /* Update bitmap image size. */ + bmi.bmiHeader.biHeight <<= 1; + bmi.bmiHeader.biSizeImage <<= 1; + + /* Allocate new buffer, doubled-up. */ + pixels = (uint8_t *)malloc(bmi.bmiHeader.biSizeImage); + + /* Copy scanlines. */ + for (i = 0; i < ys; i++) { + /* Copy original line. */ + memcpy(pixels + (i * xs * 8), + pix2 + (i * xs * 4), xs * 4); + + /* And copy it once more, doubling it. */ + memcpy(pixels + ((i * xs * 8) + (xs * 4)), + pix2 + (i * xs * 4), xs * 4); + } + + /* No longer need original buffer. */ + free(pix2); + } + + /* Save filename. */ + wcscpy(path, fn); #ifdef USE_LIBPNG /* Save the screenshot, using PNG if available. */ if (png_handle != NULL) { /* Use the PNG library. */ - SavePNG(fn, hbmp); + i = SavePNG(path, &bmi, pixels); } else { #endif /* Use BMP, so fix the file name. */ - wcscpy(temp, fn); - temp[wcslen(temp)-3] = L'b'; - temp[wcslen(temp)-2] = L'm'; - temp[wcslen(temp)-1] = L'p'; - SaveBMP(temp, hbmp); + path[wcslen(path)-3] = L'b'; + path[wcslen(path)-2] = L'm'; + path[wcslen(path)-1] = L'p'; + i = SaveBMP(path, &bmi, pixels); #ifdef USE_LIBPNG } #endif + + /* Release pixel buffer. */ + free(pixels); + + /* Show error message if needed. */ + if (i == 0) { + _swprintf(temp, get_string(IDS_ERR_SCRSHOT), path); + ui_msgbox(MBX_ERROR, temp); + } } @@ -994,114 +965,3 @@ const vidapi_t ddraw_vidapi = { ddraw_screenshot, NULL }; - - -#if 0 -@@@@@ - - if (fs) { - ddraw_w = GetSystemMetrics(SM_CXSCREEN); - ddraw_h = GetSystemMetrics(SM_CYSCREEN); - hr = lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0, 0); - if (FAILED(hr)) { - pclog("DDRAW: SetDisplayMode failed (%s)\n", GetError(hr)); - return(0); - } - } - - memset(&ddsd, 0x00, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (fs) { - ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX | DDSCAPS_FLIP); - ddsd.dwBackBufferCount = 1; - } - hr = lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL); - if (FAILED(hr)) { - pclog("DDRAW: CreateSurface failed (%s)\n", GetError(hr)); - return(0); - } - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); - if (FAILED(hr)) { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); - if (FAILED(hr)) { - pclog("DDRAW: CreateSurface back failed (%s)\n", GetError(hr)); - return(0); - } - } - - if (fs) { - ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; - hr = lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2); - if (FAILED(hr)) { - pclog("DDRAW: GetAttachedSurface failed (%s)\n", GetError(hr)); - return(0); - } - } - - memset(&ddsd, 0x00, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (fs) - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); - else - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL); - if (FAILED(hr)) { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (fs) - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL); - else - hr = lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL); - if (FAILED(hr)) { - pclog("DDRAW: CreateSurface(back) failed (%s)\n", GetError(hr)); - return(0); - } - } - - if (! fs) { - hr = lpdd4->CreateClipper(0, &lpdd_clipper, NULL); - if (FAILED(hr)) { - pclog("DDRAW: CreateClipper failed (%s)\n", GetError(hr)); - return(0); - } - - hr = lpdd_clipper->SetHWnd(0, h); - if (FAILED(hr)) { - pclog("DDRAW: SetHWnd failed (%s)\n", GetError(hr)); - return(0); - } - - hr = lpdds_pri->SetClipper(lpdd_clipper); - if (FAILED(hr)) { - pclog("DDRAW: SetClipper failed (%s)\n", GetError(hr)); - return(0); - } - } - - ddraw_hwnd = h; - - if (fs) - video_setblit(ddraw_blit_fs); - else - video_setblit(ddraw_blit); - - return(1); -} -#endif diff --git a/src/win/win_lang.c b/src/win/win_lang.c index 925765f..a0a6142 100644 --- a/src/win/win_lang.c +++ b/src/win/win_lang.c @@ -8,7 +8,7 @@ * * Handle language support for the platform. * - * Version: @(#)win_lang.c 1.0.3 2018/06/04 + * Version: @(#)win_lang.c 1.0.4 2018/06/09 * * Author: Fred N. van Kempen, * @@ -108,7 +108,7 @@ static void lang_add(lang_t *ptr, int sort) { lang_t *p, *pp; - lang_t *prev = 0; + lang_t *prev = NULL; /* Create a copy of the entry data. */ pp = (lang_t *)malloc(sizeof(lang_t)); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 3213e54..15f930a 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -12,7 +12,7 @@ * we will not use that, but, instead, use a new window which * coverrs the entire desktop. * - * Version: @(#)win_sdl.c 1.0.3 2018/05/26 + * Version: @(#)win_sdl.c 1.0.4 2018/06/10 * * Authors: Fred N. van Kempen, * Michael Dring, @@ -138,7 +138,7 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) int pitch; int yy; - if (buffer32 == NULL) { + if ((y1 == y2) || (buffer32 == NULL)) { video_blit_complete(); return; } @@ -152,7 +152,12 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) for (yy = y1; yy < y2; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer32->h) - memcpy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); +#if 0 + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w); + else +#endif + memcpy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } video_blit_complete(); @@ -194,10 +199,13 @@ sdl_close(void) if (sdl_hwnd != NULL) { plat_set_input(hwndMain); +#if 1 + ShowWindow(hwndRender, TRUE); + SetFocus(hwndMain); +#endif + DestroyWindow(sdl_hwnd); sdl_hwnd = NULL; - - SetFocus(hwndMain); } /* Quit and unload the DLL if possible. */ @@ -265,13 +273,6 @@ pclog("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd); /* Now create the SDL window from that. */ sdl_win = sdl_CreateWindowFrom((void *)sdl_hwnd); } else { - /* Redirect RawInput to this new window. */ - plat_set_input(hwndMain); - - ShowWindow(hwndRender, TRUE); - - SetFocus(hwndMain); - /* Create the SDL window from the render window. */ sdl_win = sdl_CreateWindowFrom((void *)hwndRender); } @@ -329,7 +330,89 @@ sdl_resize(int x, int y) static void sdl_screenshot(const wchar_t *fn) { - /* TODO: implement */ +#if 0 + int i, res, x, y, width = 0, height = 0; + unsigned char* rgba = NULL; + png_bytep *b_rgb = NULL; + FILE *fp = NULL; + + sdl_GetWindowSize(sdl_win, &width, &height); + + /* Create file. */ + if ((fp = plat_fopen(fn, L"wb")) == NULL) { + pclog("SDL: screenshot: file %ls could not be opened for writing\n", fn); + return; + } + + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + pclog("SDL: screenshot: create_write_struct failed\n"); + fclose(fp); + return; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + pclog("SDL: screenshot: create_info_struct failed"); + fclose(fp); + return; + } + + png_init_io(png_ptr, fp); + + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + pixels = (uint8_t *)malloc(width * height * 4); + if (pixels == NULL) { + pclog("SDL: screenshot: unable to allocate RGBA Bitmap memory\n"); + fclose(fp); + return; + } + + res = sdl_RenderReadPixels(sdl_render, NULL, + SDL_PIXELFORMAT_ABGR8888, pixels, width * 4); + if (res != 0) { + pclog("SDL: screenshot: error reading render pixels\n"); + free(pixels); + fclose(fp); + return; + } + + if ((b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * height)) == NULL) { + sdl_log("[sdl_take_screenshot] Unable to Allocate RGB Bitmap Memory"); + free(rgba); + fclose(fp); + return; + } + + for (y = 0; y < height; ++y) { + b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr)); + for (x = 0; x < width; ++x) { + b_rgb[y][(x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; + b_rgb[y][(x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; + b_rgb[y][(x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; + } + } + + png_write_info(png_ptr, info_ptr); + + png_write_image(png_ptr, b_rgb); + + png_write_end(png_ptr, NULL); + + /* cleanup heap allocation */ + for (i = 0; i < height; i++) + if (b_rgb[i]) free(b_rgb[i]); + + if (b_rgb) free(b_rgb); + + if (rgba) free(rgba); + + if (fp) fclose(fp); +#endif }