From 0f06407825daa98c065f635856f09fea0e0b794d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Mar 2018 15:16:25 +0100 Subject: [PATCH] Applied the latest PCem commits. --- src/disk/zip.c | 72 ++++++++++++++- src/scsi/scsi.h | 3 +- src/video/vid_s3.c | 106 +++++++++++++++++---- src/video/vid_sdac_ramdac.c | 178 ++++++++++++++++++++---------------- src/video/vid_sdac_ramdac.h | 2 + 5 files changed, 261 insertions(+), 100 deletions(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index eea0eedbf..1a7289503 100644 --- a/src/disk/zip.c +++ b/src/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.17 2018/03/20 + * Version: @(#)zip.c 1.0.19 2018/03/21 * * Author: Miran Grca, * @@ -99,7 +99,9 @@ const uint8_t zip_command_flags[0x100] = 0, IMPLEMENTED, /* 0x1D */ IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ + 0, IMPLEMENTED | CHECK_READY, /* 0x25 */ 0, 0, IMPLEMENTED | CHECK_READY, /* 0x28 */ @@ -1988,7 +1990,7 @@ atapi_out: zip_buf_free(id); return; } - + zip_set_buf_len(id, BufLen, &len); zip_data_command_finish(id, len, len, len, 0); @@ -2000,6 +2002,70 @@ atapi_out: zip_command_complete(id); break; + case GPCMD_READ_FORMAT_CAPACITIES: + len = (cdb[7] << 8) | cdb[8]; + + zip_buf_alloc(id, len); + memset(zipbufferb, 0, len); + + pos = 0; + + /* List header */ + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 0; + if (zip_drives[id].f != NULL) + zipbufferb[pos++] = 16; + else + zipbufferb[pos++] = 8; + + /* Current/Maximum capacity header */ + if (zip_drives[id].is_250) { + if (zip_drives[id].f != NULL) { + zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; + zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + zipbufferb[pos++] = 2; /* Current medium capacity */ + } else { + zipbufferb[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; + zipbufferb[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; + zipbufferb[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; + zipbufferb[pos++] = ZIP_250_SECTORS & 0xff; + zipbufferb[pos++] = 3; /* Maximum medium capacity */ + } + } else { + zipbufferb[pos++] = (ZIP_SECTORS >> 24) & 0xff; + zipbufferb[pos++] = (ZIP_SECTORS >> 16) & 0xff; + zipbufferb[pos++] = (ZIP_SECTORS >> 8) & 0xff; + zipbufferb[pos++] = ZIP_SECTORS & 0xff; + if (zip_drives[id].f != NULL) + zipbufferb[pos++] = 2; + else + zipbufferb[pos++] = 3; + } + + zipbufferb[pos++] = 512 >> 16; + zipbufferb[pos++] = 512 >> 8; + zipbufferb[pos++] = 512 & 0xff; + + if (zip_drives[id].f != NULL) { + /* Formattable capacity descriptor */ + zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; + zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 512 >> 16; + zipbufferb[pos++] = 512 >> 8; + zipbufferb[pos++] = 512 & 0xff; + } + + zip_set_buf_len(id, BufLen, &len); + + zip_data_command_finish(id, len, len, len, 0); + break; + default: zip_illegal_opcode(id); break; diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index 0a8239cc6..c33c5e611 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,7 +8,7 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.14 2018/03/18 + * Version: @(#)scsi_h 1.0.15 2018/03/21 * * Authors: TheCollector1995, * Miran Grca, @@ -54,6 +54,7 @@ #define GPCMD_START_STOP_UNIT 0x1b #define GPCMD_SEND_DIAGNOSTIC 0x1d #define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_FORMAT_CAPACITIES 0x23 #define GPCMD_READ_CDROM_CAPACITY 0x25 #define GPCMD_READ_10 0x28 #define GPCMD_WRITE_10 0x2a diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 22777421c..1df6e8eb3 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8,7 +8,7 @@ * * S3 emulation. * - * Version: @(#)vid_s3.c 1.0.7 2018/03/18 + * Version: @(#)vid_s3.c 1.0.8 2018/03/21 * * Authors: Sarah Walker, * Miran Grca, @@ -159,6 +159,9 @@ typedef struct s3_t uint64_t status_time; uint8_t subsys_cntl, subsys_stat; + + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; } s3_t; #define INT_VSY (1 << 0) @@ -815,15 +818,16 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (s3->chip == S3_VISION864) - { - sdac_ramdac_out(addr, val, &s3->ramdac, svga); - return; - } - else - { - break; - } + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + svga_out(addr, val, svga); + else + { + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); + else + sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); + } + return; case 0x3D4: svga->crtcreg = val & 0x7f; @@ -903,6 +907,37 @@ void s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.x <<= 1; break; + case 0x4a: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x53: case 0x58: case 0x59: case 0x5a: s3_updatemapping(s3); @@ -956,14 +991,11 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (s3->chip == S3_VISION864) - { - return sdac_ramdac_in(addr, &s3->ramdac, svga); - } - else - { - break; - } + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + return svga_in(addr, svga); + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); + return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); case 0x3d4: return svga->crtcreg; @@ -976,6 +1008,7 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: s3->hwc_col_stack_pos = 0; break; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; @@ -1977,6 +2010,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat void s3_hwcursor_draw(svga_t *svga, int displine) { + s3_t *s3 = (s3_t *)svga->p; int x; uint16_t dat[2]; int xx; @@ -1984,6 +2018,39 @@ void s3_hwcursor_draw(svga_t *svga, int displine) int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + uint32_t fg = 0, bg = 0; + + switch (svga->bpp) + { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + default: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } + else + { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } + if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -1996,7 +2063,7 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; } @@ -2268,6 +2335,7 @@ void *s3_vision864_init(const device_t *info, wchar_t *bios_fn) s3->getclock = sdac_getclock; s3->getclock_p = &s3->ramdac; + sdac_init(&s3->ramdac); return s3; } diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 37448128b..95742e26a 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -8,15 +8,13 @@ * * 87C716 'SDAC' true colour RAMDAC emulation. * - * Misidentifies as AT&T 21C504. - * - * Version: @(#)vid_sdac_ramdac.c 1.0.2 2017/11/04 + * Version: @(#)vid_sdac_ramdac.c 1.0.3 2018/03/21 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -28,72 +26,91 @@ #include "vid_svga.h" #include "vid_sdac_ramdac.h" - -/* Returning divider * 2 */ -int sdac_get_clock_divider(sdac_ramdac_t *ramdac) +static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { - switch (ramdac->command >> 4) + ramdac->command = val; + switch (val >> 4) { - case 0x1: return 1; - case 0x0: case 0x3: case 0x5: return 2; - case 0x9: return 3; - case 0x2: case 0x6: case 0x7: case 0x8: case 0xa: case 0xc: return 4; - case 0x4: case 0xe: return 6; - default: return 2; + case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; + case 0x4: case 0xe: svga->bpp = 24; break; + case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; + case 0x7: svga->bpp = 32; break; + + case 0: case 1: default: svga->bpp = 8; break; } } +static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) +{ + if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) + { + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + } + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->windex++; +} + +static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) +{ + uint8_t temp; + + if (!ramdac->reg_ff) + temp = ramdac->regs[reg] & 0xff; + else + temp = ramdac->regs[reg] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->rindex++; + + return temp; +} + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { switch (addr) - { - case 0x3C6: - if (val == 0xff) - { - ramdac->rs2 = 0; - ramdac->magic_count = 0; - break; - } - if (ramdac->magic_count < 4) break; + { + case 2: if (ramdac->magic_count == 4) - { - ramdac->command = val; - switch (val >> 4) - { - case 0x2: case 0x3: case 0x8: case 0xa: svga->bpp = 15; break; - case 0x4: case 0x9: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: case 0xd: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } - svga_recalctimings(svga); - pclog("RAMDAC: Mode: %i, BPP: %i\n", val >> 4, svga->bpp); - } + sdac_control_write(ramdac, svga, val); + ramdac->magic_count = 0; break; - case 0x3C7: + case 3: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->rindex = val; break; - case 0x3C8: + case 0: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->windex = val; break; - case 0x3C9: + case 1: ramdac->magic_count = 0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0xff00) | val; - else ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0x00ff) | (val << 8); - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) ramdac->windex++; - } + break; + + case 4: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 5: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 6: + sdac_control_write(ramdac, svga, val); + break; + case 7: + ramdac->rindex = val; + ramdac->reg_ff = 0; break; } - svga_out(addr, val, svga); + if (!(addr & 4)) + { + if (addr < 2) + svga_out(addr + 0x3c8, val, svga); + else + svga_out(addr + 0x3c4, val, svga); + } } uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) @@ -101,10 +118,9 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) uint8_t temp; switch (addr) { - case 0x3C6: - ramdac->reg_ff = 0; + case 2: if (ramdac->magic_count < 5) - ramdac->magic_count++; + ramdac->magic_count++; if (ramdac->magic_count == 4) { temp = 0x70; /*SDAC ID*/ @@ -116,31 +132,33 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) ramdac->magic_count = 0; } return temp; - case 0x3C7: - ramdac->magic_count=0; - if (ramdac->rs2) return ramdac->rindex; + case 3: + ramdac->magic_count=0; break; - case 0x3C8: - ramdac->magic_count=0; - if (ramdac->rs2) return ramdac->windex; + case 0: + ramdac->magic_count=0; break; - case 0x3C9: - ramdac->magic_count=0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex & 0xff] & 0xff; - else temp = ramdac->regs[ramdac->rindex & 0xff] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - { - ramdac->rindex++; - ramdac->magic_count = 0; - } - return temp; - } + case 1: + ramdac->magic_count=0; break; + + case 4: + return ramdac->windex; + case 5: + return sdac_reg_read(ramdac, ramdac->rindex & 0xff); + case 6: + return ramdac->command; + case 7: + return ramdac->rindex; } - return svga_in(addr, svga); + if (!(addr & 4)) + { + if (addr < 2) + return svga_in(addr + 0x3c8, svga); + else + return svga_in(addr + 0x3c4, svga); + } + return 0xff; } float sdac_getclock(int clock, void *p) @@ -157,3 +175,9 @@ float sdac_getclock(int clock, void *p) t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); return t; } + +void sdac_init(sdac_ramdac_t *ramdac) +{ + ramdac->regs[0] = 0x6128; + ramdac->regs[1] = 0x623d; +} diff --git a/src/video/vid_sdac_ramdac.h b/src/video/vid_sdac_ramdac.h index e2a8557bb..52d908599 100644 --- a/src/video/vid_sdac_ramdac.h +++ b/src/video/vid_sdac_ramdac.h @@ -11,6 +11,8 @@ typedef struct sdac_ramdac_t int rs2; } sdac_ramdac_t; +void sdac_init(sdac_ramdac_t *ramdac); + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);