diff --git a/src/device.c b/src/device.c index 87fb467..ed2e666 100644 --- a/src/device.c +++ b/src/device.c @@ -135,6 +135,7 @@ device_add(const device_t *d) { wchar_t temp[1024]; void *priv = NULL; + device_t *old; int c; for (c = 0; c < DEVICE_MAX; c++) { @@ -164,6 +165,7 @@ device_add(const device_t *d) INFO("DEVICE: device '%s' is unstable, user agreed!\n", d->name); } + old = device_current; device_current = (device_t *)d; devices[c] = (device_t *)d; @@ -183,6 +185,7 @@ device_add(const device_t *d) } device_priv[c] = priv; + device_current = old; return(priv); } @@ -204,8 +207,6 @@ device_add_ex(const device_t *d, void *priv) if (c >= DEVICE_MAX) fatal("DEVICE: too many devices\n"); - device_current = (device_t *)d; - devices[c] = (device_t *)d; device_priv[c] = priv; } diff --git a/src/devices/cdrom/cdrom.c b/src/devices/cdrom/cdrom.c index b4ff947..b872ccb 100644 --- a/src/devices/cdrom/cdrom.c +++ b/src/devices/cdrom/cdrom.c @@ -8,7 +8,7 @@ * * Generic interface for CD-ROM/DVD/BD implementations. * - * Version: @(#)cdrom.c 1.0.24 2018/10/20 + * Version: @(#)cdrom.c 1.0.25 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -271,7 +271,7 @@ cdrom_eject(uint8_t id) } if (dev->host_drive == 200) { - dev->prev_image_path = (wchar_t *)mem_alloc(1024); + dev->prev_image_path = (wchar_t *)mem_alloc(1024 * sizeof(wchar_t)); wcscpy(dev->prev_image_path, dev->image_path); } diff --git a/src/devices/cdrom/cdrom_image.cpp b/src/devices/cdrom/cdrom_image.cpp index 520e2ea..293d381 100644 --- a/src/devices/cdrom/cdrom_image.cpp +++ b/src/devices/cdrom/cdrom_image.cpp @@ -8,7 +8,7 @@ * * CD-ROM image support. * - * Version: @(#)cdrom_image.cpp 1.0.17 2018/10/20 + * Version: @(#)cdrom_image.cpp 1.0.19 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -133,7 +133,7 @@ enum { static int cdrom_sector_size; -static uint8_t raw_buffer[2448]; +static uint8_t raw_buffer[2856]; /* same size as sector_buffer_t */ static uint8_t extra_buffer[296]; @@ -467,9 +467,9 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i bb += mode2 ? 12 : 4; bb += len; if (mode2 && ((mode2 & 0x03) == 1)) - memset(bb, 0, 280); + memset(bb, 0, 88); /* 280 */ else if (!mode2) - memset(bb, 0, 288); + memset(bb, 0, 96); /* 288 */ } @@ -730,13 +730,8 @@ image_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int is_msf, if (!is_legal(dev->id, type, flags, audio, mode2)) return 0; - if ((type == 3) || ((type > 4) && (type != 8))) { - if (type == 3) { - DEBUG("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", dev->id); - } - if (type > 4) { - DEBUG("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", dev->id); - } + if ((type > 5) && (type != 8)) { + DEBUG("CD-ROM %i: Attempting to read an unrecognized sector type from an image\n", dev->id); return 0; } else if (type == 1) { if (!audio || dev->img_is_iso) { @@ -1107,6 +1102,7 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn) if (! img->SetDevice(temp, false)) { image_close(dev); dev->ops = NULL; + dev->host_drive = 0; return 1; } diff --git a/src/devices/disk/zip.c b/src/devices/disk/zip.c index 3af09bb..5791fb2 100644 --- a/src/devices/disk/zip.c +++ b/src/devices/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.20 2018/10/20 + * Version: @(#)zip.c 1.0.21 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -2760,15 +2760,15 @@ zip_identify(void *p, int ide_has_dma) } -static zip_t * +static void zip_drive_reset(int c) { scsi_device_t *sd; ide_t *id; if (!zip[c]) { - zip[c] = (zip_t *) malloc(sizeof(zip_t)); - memset(zip[c], 0, sizeof(zip_t)); + zip[c] = (zip_t *)mem_alloc(sizeof(zip_t)); + memset(zip[c], 0x00, sizeof(zip_t)); } zip[c]->id = c; @@ -2807,8 +2807,6 @@ zip_drive_reset(int c) ide_atapi_attach(id); } } - - return zip[c]; } @@ -2829,7 +2827,7 @@ zip_hard_reset(void) if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].bus_id.ide_channel > 7)) continue; - zip[c] = zip_drive_reset(c); + zip_drive_reset(c); zip[c]->id = c; zip[c]->drv = &zip_drives[c]; diff --git a/src/devices/input/mouse_bus.c b/src/devices/input/mouse_bus.c index 1af7a3a..76cd434 100644 --- a/src/devices/input/mouse_bus.c +++ b/src/devices/input/mouse_bus.c @@ -40,6 +40,8 @@ * Logitech Mouse.exe 6.50 * Microsoft Mouse.com 2.00 * Microsoft Mouse.sys 3.00 + * Microsoft Mouse.com 7.04 + * Microsoft Mouse.com 8.21J * Microsoft Windows 1.00 DR5 * Microsoft Windows 3.10.026 * Microsoft Windows NT 3.1 @@ -51,7 +53,7 @@ * Microsoft Windows NT 3.1 * Microsoft Windows 98 SE * - * Version: @(#)mouse_bus.c 1.1.1 2018/10/11 + * Version: @(#)mouse_bus.c 1.1.2 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/devices/scsi/scsi_x54x.h b/src/devices/scsi/scsi_x54x.h index 5105389..0e3a6dc 100644 --- a/src/devices/scsi/scsi_x54x.h +++ b/src/devices/scsi/scsi_x54x.h @@ -8,7 +8,7 @@ * * Definitions for the common AHA/BL code. * - * Version: @(#)scsi_x54x.h 1.0.5 2018/10/14 + * Version: @(#)scsi_x54x.h 1.0.6 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -133,50 +133,10 @@ #define INTR_MBIF 0x01 /* MBI full */ -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - #define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) #define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) -/* Structure for the INQUIRE_SETUP_INFORMATION reply. */ -#pragma pack(push,1) -typedef struct { - uint8_t uOffset :4, - uTransferPeriod :3, - fSynchronous :1; -} ReplyInquireSetupInformationSynchronousValue; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t fSynchronousInitiationEnabled :1, - fParityCheckingEnabled :1, - uReserved1 :6; - uint8_t uBusTransferRate; - uint8_t uPreemptTimeOnBus; - uint8_t uTimeOffBus; - uint8_t cMailbox; - addr24 MailboxAddress; - ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; - uint8_t uDisconnectPermittedId0To7; - uint8_t VendorSpecificData[28]; -} ReplyInquireSetupInformation; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t Count; - addr24 Address; -} MailboxInit_t; -#pragma pack(pop) - /* * Mailbox Definitions. * @@ -193,31 +153,6 @@ typedef struct { #define MBI_NOT_FOUND 0x03 #define MBI_ERROR 0x04 -#pragma pack(push,1) -typedef struct { - uint8_t CmdStatus; - addr24 CCBPointer; -} Mailbox_t; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint32_t CCBPointer; - union { - struct { - uint8_t Reserved[3]; - uint8_t ActionCode; - } out; - struct { - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved; - uint8_t CompletionCode; - } in; - } u; -} Mailbox32_t; -#pragma pack(pop) - /* * * CCB - SCSI Command Control Block @@ -265,13 +200,77 @@ typedef struct { #define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */ #define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */ +#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \ + (p->u.lba.lba2<<8) | p->u.lba.lba3) +/* + * + * Scatter/Gather Segment List Definitions + * + * Adapter limits + */ +#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ + + +#pragma pack(push,1) +typedef struct { + uint8_t hi; + uint8_t mid; + uint8_t lo; +} addr24; + +/* Structure for the INQUIRE_SETUP_INFORMATION reply. */ +typedef struct { + uint8_t uOffset :4, + uTransferPeriod :3, + fSynchronous :1; +} ReplyInquireSetupInformationSynchronousValue; +typedef struct { + uint8_t fSynchronousInitiationEnabled :1, + fParityCheckingEnabled :1, + uReserved1 :6; + uint8_t uBusTransferRate; + uint8_t uPreemptTimeOnBus; + uint8_t uTimeOffBus; + uint8_t cMailbox; + addr24 MailboxAddress; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; + uint8_t uDisconnectPermittedId0To7; + uint8_t VendorSpecificData[28]; +} ReplyInquireSetupInformation; + +typedef struct { + uint8_t Count; + addr24 Address; +} MailboxInit_t; + +typedef struct { + uint8_t CmdStatus; + addr24 CCBPointer; +} Mailbox_t; + +typedef struct { + uint32_t CCBPointer; + union { + struct { + uint8_t Reserved[3]; + uint8_t ActionCode; + } out; + struct { + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved; + uint8_t CompletionCode; + } in; + } u; +} Mailbox32_t; + + /* Byte 15 Target Status See scsi.h files for these statuses. Bytes 16 and 17 Reserved (must be 0) Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ -#pragma pack(push,1) typedef struct { uint8_t Opcode; uint8_t Reserved1 :3, @@ -293,9 +292,7 @@ typedef struct { uint8_t Reserved3[6]; uint32_t SensePointer; } CCB32; -#pragma pack(pop) -#pragma pack(push,1) typedef struct { uint8_t Opcode; uint8_t Lun :3, @@ -312,9 +309,7 @@ typedef struct { uint8_t Reserved[2]; uint8_t Cdb[12]; } CCB; -#pragma pack(pop) -#pragma pack(push,1) typedef struct { uint8_t Opcode; uint8_t Pad1 :3, @@ -329,17 +324,13 @@ typedef struct { uint8_t Pad4[2]; uint8_t Cdb[12]; } CCBC; -#pragma pack(pop) -#pragma pack(push,1) typedef union { CCB32 new_fmt; CCB old_fmt; CCBC common; } CCBU; -#pragma pack(pop) -#pragma pack(push,1) typedef struct { CCBU CmdBlock; uint8_t *RequestSenseBuffer; @@ -351,6 +342,38 @@ typedef struct { TargetStatus, MailboxCompletionCode; } Req_t; + +typedef struct { + uint8_t command; + uint8_t lun:3, + reserved:2, + id:3; + union { + struct { + uint16_t cyl; + uint8_t head; + uint8_t sec; + } chs; + struct { + uint8_t lba0; /* MSB */ + uint8_t lba1; + uint8_t lba2; + uint8_t lba3; /* LSB */ + } lba; + } u; + uint8_t secount; + addr24 dma_address; +} BIOSCMD; + +typedef struct { + uint32_t Segment; + uint32_t SegmentPointer; +} SGE32; + +typedef struct { + addr24 Segment; + addr24 SegmentPointer; +} SGE; #pragma pack(pop) typedef struct { @@ -490,56 +513,6 @@ typedef struct { } x54x_t; -#pragma pack(push,1) -typedef struct -{ - uint8_t command; - uint8_t lun:3, - reserved:2, - id:3; - union { - struct { - uint16_t cyl; - uint8_t head; - uint8_t sec; - } chs; - struct { - uint8_t lba0; /* MSB */ - uint8_t lba1; - uint8_t lba2; - uint8_t lba3; /* LSB */ - } lba; - } u; - uint8_t secount; - addr24 dma_address; -} BIOSCMD; -#pragma pack(pop) -#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \ - (p->u.lba.lba2<<8) | p->u.lba.lba3) - -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - - extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset); extern void x54x_buf_alloc(scsi_device_t *sd, int length); extern void x54x_buf_free(scsi_device_t *sd); diff --git a/src/devices/video/vid_bt48x_ramdac.c b/src/devices/video/vid_bt48x_ramdac.c index b7caf75..8f745d9 100644 --- a/src/devices/video/vid_bt48x_ramdac.c +++ b/src/devices/video/vid_bt48x_ramdac.c @@ -8,7 +8,7 @@ * * Brooktree Bt48x series true color RAMDAC emulation. * - * Version: @(#)vid_bt48x_ramdac.c 1.0.8 2018/10/06 + * Version: @(#)vid_bt48x_ramdac.c 1.0.9 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -209,8 +209,10 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *d indx = svga->dac_addr & 0x03ff; if ((dev->type >= BT485) && (svga->hwcursor.xsize == 64)) cd = (uint8_t *) dev->cursor64_data; - else + else { + indx &= 0xff; cd = (uint8_t *) dev->cursor32_data; + } cd[indx] = val; svga->dac_addr++; svga->dac_addr = (svga->dac_addr + 1) & da_mask; @@ -351,8 +353,10 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *dev, svga_t *sv indx = (svga->dac_addr - 1) & da_mask; if ((dev->type >= BT485) && (svga->hwcursor.xsize == 64)) cd = (uint8_t *) dev->cursor64_data; - else + else { + indx &= 0xff; cd = (uint8_t *) dev->cursor32_data; + } temp = cd[indx]; svga->dac_addr = (svga->dac_addr + 1) & da_mask; diff --git a/src/devices/video/vid_cl54xx.c b/src/devices/video/vid_cl54xx.c index bd65c0a..02ebcfb 100644 --- a/src/devices/video/vid_cl54xx.c +++ b/src/devices/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, 5430, 5434 and 5436 are supported). * - * Version: @(#)vid_cl54xx.c 1.0.21 2018/10/20 + * Version: @(#)vid_cl54xx.c 1.0.22 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1016,8 +1016,13 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) { + + if ((svga->seqregs[0x07] & 0x01) == 0) { + svga_write(addr, val, svga); + return; + } + + if (gd54xx->blt.sys_tx) { if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); @@ -1028,7 +1033,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p) } } return; - } + } addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; @@ -1043,13 +1048,17 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p) gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val & 0xff, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - return; - } - + if ((svga->seqregs[0x07] & 0x01) == 0) { + svga_writew(addr, val, svga); + return; + } + + if (gd54xx->blt.sys_tx) { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr+1, val >> 8, gd54xx); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; @@ -1068,14 +1077,18 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p) gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val & 0xff, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - return; - } + if ((svga->seqregs[0x07] & 0x01) == 0) { + svga_writel(addr, val, svga); + return; + } + + if (gd54xx->blt.sys_tx) { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr+1, val >> 8, gd54xx); + gd54xx_write(addr+2, val >> 16, gd54xx); + gd54xx_write(addr+3, val >> 24, gd54xx); + return; + } addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; @@ -1532,8 +1545,13 @@ gd54xx_read(uint32_t addr, void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; + + if ((svga->seqregs[0x07] & 0x01) == 0) + return svga_read(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_read_linear(addr, svga); } @@ -1544,8 +1562,12 @@ gd54xx_readw(uint32_t addr, void *p) gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; + if ((svga->seqregs[0x07] & 0x01) == 0) + return svga_readw(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_readw_linear(addr, svga); } @@ -1556,8 +1578,12 @@ gd54xx_readl(uint32_t addr, void *p) gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; + if ((svga->seqregs[0x07] & 0x01) == 0) + return svga_readl(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + return svga_readl_linear(addr, svga); } @@ -1567,8 +1593,8 @@ gd543x_do_mmio(svga_t *svga, uint32_t addr) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) return 1; - else - return ((addr & ~0xff) == 0xb8000); + + return ((addr & ~0xff) == 0xb8000); } @@ -1795,6 +1821,7 @@ gd543x_mmio_read(uint32_t addr, void *p) } else if (gd54xx->mmio_vram_overlap) return gd54xx_read(addr, gd54xx); + return 0xff; } @@ -1809,6 +1836,7 @@ gd543x_mmio_readw(uint32_t addr, void *p) return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8); else if (gd54xx->mmio_vram_overlap) return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8); + return 0xffff; } @@ -1823,6 +1851,7 @@ gd543x_mmio_readl(uint32_t addr, void *p) return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24); else if (gd54xx->mmio_vram_overlap) return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24); + return 0xffffffff; } diff --git a/src/devices/video/vid_svga.c b/src/devices/video/vid_svga.c index 1c586cf..fe6e5bf 100644 --- a/src/devices/video/vid_svga.c +++ b/src/devices/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.13 2018/10/07 + * Version: @(#)vid_svga.c 1.0.14 2018/10/21 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -875,15 +875,39 @@ void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; - - int func_select, writemask2 = svga->writemask; uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val; + int func_select, writemask2 = svga->writemask; + int memory_map_mode; cycles -= video_timing_write_b; - if (!linear) { - addr &= svga->banked_mask; - addr += svga->write_bank; + if (! linear) { + memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + addr &= 0x1ffff; + + switch (memory_map_mode) { + case 0: + break; + + case 1: + if (addr >= 0x10000) + return; + addr += svga->write_bank; + break; + + case 2: + addr -= 0x10000; + if (addr >= 0x8000) + return; + break; + + default: + case 3: + addr -= 0x18000; + if (addr >= 0x8000) + return; + break; + } } if (!(svga->gdcreg[6] & 1)) @@ -1008,14 +1032,38 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; uint32_t latch_addr = 0, ret; - int readplane = svga->readplane; - uint8_t ret8; + int memory_map_mode, readplane = svga->readplane; cycles -= video_timing_read_b; - if (!linear) { - addr &= svga->banked_mask; - addr += svga->read_bank; + if (! linear) { + memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + + addr &= 0x1ffff; + + switch(memory_map_mode) { + case 0: + break; + + case 1: + if (addr >= 0x10000) + return 0xff; + addr += svga->read_bank; + break; + + case 2: + addr -= 0x10000; + if (addr >= 0x8000) + return 0xff; + break; + + default: + case 3: + addr -= 0x18000; + if (addr >= 0x8000) + return 0xff; + break; + } latch_addr = (addr << 2) & svga->decode_mask; } @@ -1029,6 +1077,12 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) readplane = (readplane & 2) | (addr & 1); addr &= ~1; addr <<= 2; + addr |= readplane; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + addr &= svga->vram_mask; + return svga->vram[addr]; } else addr <<= 2; @@ -1058,16 +1112,15 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) if (!(svga->gdcreg[5] & 8)) { /* read mode 0 */ - return svga->vram[addr | readplane]; - } else { - /* read mode 1 */ - ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f]; - ret8 = (ret & 0xff); - ret8 |= ((ret >> 24) & 0xff); - ret8 |= ((ret >> 16) & 0xff); - ret8 |= ((ret >> 8) & 0xff); - return(~ret8); + return (svga->latch >> (readplane * 8)) & 0xff; } + + /* read mode 1 */ + ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f]; + ret |= ret >> 16; + ret |= ret >> 8; + ret = (~ret) & 0xff; + return(ret); } diff --git a/src/ui/ui_stbar.c b/src/ui/ui_stbar.c index f7e74e3..7215e70 100644 --- a/src/ui/ui_stbar.c +++ b/src/ui/ui_stbar.c @@ -877,7 +877,7 @@ ui_sb_menu_command(int idm, uint8_t tag) /* Save current drive/pathname for later re-use. */ cdev->prev_host_drive = cdev->host_drive; if (! cdev->prev_image_path) - cdev->prev_image_path = (wchar_t *)mem_alloc(1024); + cdev->prev_image_path = (wchar_t *)mem_alloc(1024 * sizeof(wchar_t)); wcscpy(cdev->prev_image_path, str); /* Close the current drive/pathname. */ diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 342463c..1f3fc49 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.5 2018/10/05 + * Version: @(#)win_sdl.c 1.0.6 2018/10/21 * * Authors: Fred N. van Kempen, * Michael Drüing, @@ -83,7 +83,10 @@ static SDL_Window *sdl_win = NULL; static SDL_Renderer *sdl_render = NULL; static SDL_Texture *sdl_tex = NULL; static HWND sdl_hwnd = NULL; +static HWND sdl_parent_hwnd = NULL; static int sdl_w, sdl_h; +static int cur_w, cur_h; +static int sdl_fs; /* Pointers to the real functions. */ @@ -130,15 +133,131 @@ static const dllimp_t sdl_imports[] = { }; +static void +sdl_stretch(int *w, int *h, int *x, int *y) +{ + double dw, dh, dx, dy, temp, temp2, ratio_w, ratio_h, gsr, hsr; + + switch (vid_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + *w = sdl_w; + *h = sdl_h; + *x = 0; + *y = 0; + break; + + case FULLSCR_SCALE_43: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = (dh / 3.0) * 4.0; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = 0; + break; + + case FULLSCR_SCALE_SQ: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = ((double) *w); + temp2 = ((double) *h); + dx = (dw / 2.0) - ((dh * temp) / (temp2 * 2.0)); + dy = 0.0; + if (dx < 0.0) { + dx = 0.0; + dy = (dw / 2.0) - ((dh * temp2) / (temp * 2.0)); + } + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + + case FULLSCR_SCALE_INT: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = ((double) *w); + temp2 = ((double) *h); + ratio_w = dw / ((double) *w); + ratio_h = dh / ((double) *h); + if (ratio_h < ratio_w) + ratio_w = ratio_h; + dx = (dw / 2.0) - ((temp * ratio_w) / 2.0); + dy = (dh / 2.0) - ((temp2 * ratio_h) / 2.0); + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + + case FULLSCR_SCALE_KEEPRATIO: + dw = (double) sdl_w; + dh = (double) sdl_h; + hsr = dw / dh; + gsr = ((double) *w) / ((double) *h); + if (gsr <= hsr) { + temp = dh * gsr; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = 0; + } else { + temp = dw / gsr; + dy = (dh - temp) / 2.0; + dh = temp; + *w = (int) dw; + *h = (int) dh; + *x = 0; + *y = (int) dy; + } + break; + } +} + + +static void +sdl_resize(int x, int y) +{ + int ww = 0, wh = 0, wx = 0, wy = 0; + + DEBUG("SDL: resizing to %dx%d\n", x, y); + + if ((x == cur_w) && (y == cur_h)) return; + + DEBUG("sdl_resize(%i, %i)\n", x, y); + ww = x; + wh = y; + sdl_stretch(&ww, &wh, &wx, &wy); + + MoveWindow(sdl_hwnd, wx, wy, ww, wh, TRUE); + + cur_w = x; + cur_h = y; +} + + static void sdl_blit(int x, int y, int y1, int y2, int w, int h) { SDL_Rect r_src; void *pixeldata; + int xx, yy, ret; int pitch; - int yy; - if ((y1 == y2) || (buffer32 == NULL)) { + if (y1 == y2) { + video_blit_complete(); + return; + } + + if (buffer32 == NULL) { video_blit_complete(); return; } @@ -151,25 +270,34 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) sdl_LockTexture(sdl_tex, 0, &pixeldata, &pitch); for (yy = y1; yy < y2; yy++) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) -#if 0 - if (video_grayscale || invert_display) + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (vid_grayscale || invert_display) video_transform_copy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w); - else -#endif + else memcpy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } } video_blit_complete(); sdl_UnlockTexture(sdl_tex); + if (sdl_fs) { + get_screen_size_natural(&xx, &yy); + DEBUG("sdl_blit(%i, %i, %i, %i, %i, %i) (%i, %i)\n", x, y, y1, y2, w, h, xx, yy); + if (w == xx) + sdl_resize(w, h); + DEBUG("(%08X, %08X, %08X)\n", sdl_win, sdl_render, sdl_tex); + } + r_src.x = 0; r_src.y = 0; r_src.w = w; r_src.h = h; - sdl_RenderCopy(sdl_render, sdl_tex, &r_src, 0); + ret = sdl_RenderCopy(sdl_render, sdl_tex, &r_src, 0); + if (ret) + DEBUG("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); sdl_RenderPresent(sdl_render); } @@ -199,15 +327,18 @@ 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; } + if (sdl_parent_hwnd != NULL) { + DestroyWindow(sdl_parent_hwnd); + sdl_parent_hwnd = NULL; + } + /* Quit and unload the DLL if possible. */ if (sdl_handle != NULL) { sdl_Quit(); @@ -223,6 +354,7 @@ sdl_init(int fs) { wchar_t temp[128]; SDL_version ver; + int x, y; INFO("SDL: init (fs=%d)\n", fs); @@ -253,7 +385,7 @@ sdl_init(int fs) /* Create the desktop-covering window. */ swprintf(temp, sizeof_w(temp), L"%s v%s Full-Screen", EMU_NAME, emu_version); - sdl_hwnd = CreateWindow(FS_CLASS_NAME, + sdl_parent_hwnd = CreateWindow(FS_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h, @@ -261,12 +393,28 @@ sdl_init(int fs) NULL, hInstance, NULL); + + SetWindowPos(sdl_parent_hwnd, HWND_TOPMOST, + 0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW); + + /* Create the actual rendering window. */ + swprintf(temp, sizeof_w(temp), L"%s v%s", EMU_NAME, emu_version); + sdl_hwnd = CreateWindow(FS_CLASS_NAME, + temp, + WS_POPUP, + 0, 0, sdl_w, sdl_h, + sdl_parent_hwnd, + NULL, + hInstance, + NULL); DEBUG("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd); /* Redirect RawInput to this new window. */ plat_set_input(sdl_hwnd); /* Show the window, make it topmost, and give it focus. */ + get_screen_size_natural(&x, &y); + sdl_stretch(&sdl_w, &sdl_h, &x, &y); SetWindowPos(sdl_hwnd, HWND_TOPMOST, 0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW); @@ -276,11 +424,13 @@ sdl_init(int fs) /* Create the SDL window from the render window. */ sdl_win = sdl_CreateWindowFrom((void *)hwndRender); } + if (sdl_win == NULL) { ERRLOG("SDL: unable to CreateWindowFrom (%s)\n", sdl_GetError()); sdl_close(); return(0); } + sdl_fs = fs; /* * TODO: @@ -320,55 +470,18 @@ sdl_init(int fs) } -static void -sdl_resize(int x, int y) -{ - DEBUG("SDL: resizing to %dx%d\n", x, y); -} - - static void sdl_screenshot(const wchar_t *fn) { #if 0 - int i, res, x, y, width = 0, height = 0; - unsigned char* rgba = NULL; - png_bytep *b_rgb = NULL; - FILE *fp = NULL; + uint8_t *pixels = NULL; + int res; sdl_GetWindowSize(sdl_win, &width, &height); - /* Create file. */ - if ((fp = plat_fopen(fn, L"wb")) == NULL) { - ERRLOG("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) { - ERRLOG("SDL: screenshot: create_write_struct failed\n"); - fclose(fp); - return; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - ERRLOG("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 *)mem_alloc(width * height * 4); if (pixels == NULL) { ERRLOG("SDL: screenshot: unable to allocate RGBA Bitmap memory\n"); - fclose(fp); return; } @@ -377,41 +490,10 @@ sdl_screenshot(const wchar_t *fn) if (res != 0) { ERRLOG("SDL: screenshot: error reading render pixels\n"); free(pixels); - fclose(fp); return; } - if ((b_rgb = (png_bytep *)mem_alloc(sizeof(png_bytep) * height)) == NULL) { - ERRLOG("[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 *)mem_alloc(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); + if (pixels) free(pixels); #endif }