From 99c85176fff0f3673c671ae0bfbd1448c6cb378a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 4 Dec 2011 14:24:14 +0200 Subject: [PATCH] 2400b2 --- audio.cpp | 2 + cfgfile.cpp | 4 +- custom.cpp | 8 +- drawing.cpp | 16 +- filesys.cpp | 2 + gayle.cpp | 562 ++++++++++++++++++++++++++--------- hardfile.cpp | 4 +- include/gayle.h | 2 + main.cpp | 6 +- od-win32/win32.cpp | 5 + od-win32/win32.h | 6 +- od-win32/win32_filesys.cpp | 6 +- od-win32/win32_scaler.cpp | 2 + od-win32/win32gfx.cpp | 35 ++- od-win32/win32gui.cpp | 7 +- od-win32/winuaechangelog.txt | 61 ++++ od-win32/writelog.cpp | 2 +- specialmonitors.cpp | 206 ++++++++----- 18 files changed, 707 insertions(+), 229 deletions(-) diff --git a/audio.cpp b/audio.cpp index ed3f01ae..4d426129 100644 --- a/audio.cpp +++ b/audio.cpp @@ -65,6 +65,8 @@ static bool debugchannel (int ch) STATIC_INLINE bool usehacks (void) { + if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68020) + return false; return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0; } diff --git a/cfgfile.cpp b/cfgfile.cpp index e853b2cd..190a2a2d 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -505,7 +505,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) TCHAR *hdcontrollers[] = { L"uae", L"ide0", L"ide1", L"ide2", L"ide3", L"scsi0", L"scsi1", L"scsi2", L"scsi3", L"scsi4", L"scsi5", L"scsi6", - L"scsram", L"scside" }; /* scsram = smart card sram = pcmcia sram card */ + L"scsram", L"scide" }; /* scsram = smart card sram = pcmcia sram card */ for (i = 0; i < p->mountitems; i++) { struct uaedev_config_info *uci = &p->mountconfig[i]; @@ -2620,6 +2620,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, L"scsram", 6)) hdcv = HD_CONTROLLER_PCMCIA_SRAM; + if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, L"scide", 6)) + hdcv = HD_CONTROLLER_PCMCIA_IDE; } } } diff --git a/custom.cpp b/custom.cpp index a468df36..8420bbe7 100644 --- a/custom.cpp +++ b/custom.cpp @@ -2958,8 +2958,6 @@ void init_hz (bool fullinit) res2 = RES_MAX; vres2 = currprefs.gfx_vresolution; - if (islace && !vres2) - vres2++; if (doublescan && !islace) vres2--; @@ -2976,11 +2974,13 @@ void init_hz (bool fullinit) gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; } else { + gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; - gfxvidinfo.drawbuffer.extrawidth = 8; + gfxvidinfo.drawbuffer.extrawidth = 1; gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << currprefs.gfx_vresolution; gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; + } @@ -7294,7 +7294,7 @@ STATIC_INLINE int dma_cycle (void) blitter_nasty = 1; if (cpu_tracer == -1) return current_hpos (); - for (;;) { + while (currprefs.cpu_cycle_exact) { int bpldma; int blitpri = dmacon & DMA_BLITPRI; hpos_old = current_hpos (); diff --git a/drawing.cpp b/drawing.cpp index 3f70b7bf..43d095c8 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -2232,7 +2232,7 @@ static void center_image (void) } } else if (gfxvidinfo.drawbuffer.extrawidth) { visible_left_border = max_diwlastword - w; - visible_left_border += gfxvidinfo.drawbuffer.extrawidth << currprefs.gfx_resolution; + //visible_left_border += gfxvidinfo.drawbuffer.extrawidth << currprefs.gfx_resolution; } else { visible_left_border = 0; } @@ -2862,6 +2862,17 @@ void notice_interlace_seen (void) interlace_seen = 1; } +static void clearbuffer(struct vidbuffer *dst) +{ + if (!dst->bufmem_allocated) + return; + uae_u8 *p = dst->bufmem; + for (int y = 0; y < dst->height; y++) { + memset(p, 0, dst->width * dst->pixbytes); + p += dst->rowbytes; + } +} + void reset_drawing (void) { unsigned int i; @@ -2889,6 +2900,9 @@ void reset_drawing (void) lightpen_y1 = lightpen_y2 = -1; reset_custom_limits (); + + clearbuffer (&gfxvidinfo.drawbuffer); + clearbuffer (&gfxvidinfo.tempbuffer); } void drawing_init (void) diff --git a/filesys.cpp b/filesys.cpp index f1083f98..df62665f 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -638,6 +638,8 @@ static void initialize_mountinfo (void) } } else if (uci->controller == HD_CONTROLLER_PCMCIA_SRAM) { gayle_add_pcmcia_sram_unit (uci->rootdir, uci->readonly); + } else if (uci->controller == HD_CONTROLLER_PCMCIA_IDE) { + gayle_add_pcmcia_ide_unit (uci->rootdir, uci->readonly); } } filesys_addexternals (); diff --git a/gayle.cpp b/gayle.cpp index 046565ab..159ddac1 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -27,6 +27,9 @@ #include "a2091.h" #include "ncr_scsi.h" +#define PCMCIA_SRAM 1 +#define PCMCIA_IDE 2 + /* 600000 to 9FFFFF 4 MB Credit Card memory if CC present A00000 to A1FFFF 128 KB Credit Card Attributes @@ -162,6 +165,7 @@ struct ide_registers { uae_u8 ide_select, ide_nsector, ide_sector, ide_lcyl, ide_hcyl, ide_devcon, ide_error, ide_feat; uae_u8 ide_nsector2, ide_sector2, ide_lcyl2, ide_hcyl2, ide_feat2; + uae_u8 ide_drv; }; struct ide_hdf @@ -184,15 +188,23 @@ struct ide_hdf int maxtransferstate; }; -static struct ide_hdf *idedrive[4]; -static struct ide_registers ideregs[2]; +#define TOTAL_IDE 3 +#define GAYLE_IDE_ID 0 +#define PCMCIA_IDE_ID 2 + +static struct ide_hdf *idedrive[TOTAL_IDE * 2]; +static struct ide_registers ideregs[TOTAL_IDE]; struct hd_hardfiledata *pcmcia_sram; + static int pcmcia_card; static int pcmcia_readonly; +static int pcmcia_type; +static uae_u8 pcmcia_configuration[20]; +static bool pcmcia_configured; static int gayle_id_cnt; static uae_u8 gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg; -static int ide_drv, ide2, ide_splitter; +static int ide2, ide_splitter; static struct ide_hdf *ide; @@ -219,7 +231,26 @@ static void ps (int offset, const TCHAR *src, int max) xfree (s); } -static int isideirq (void) +static void pcmcia_reset (void) +{ + memset (pcmcia_configuration, 0, sizeof pcmcia_configuration); + pcmcia_configured = false; + if (PCMCIA_LOG > 0) + write_log (L"PCMCIA reset\n"); +} + +static uae_u8 checkpcmciaideirq (void) +{ + if (!idedrive || pcmcia_type != PCMCIA_IDE || !pcmcia_configured) + return 0; + if (ideregs[PCMCIA_IDE_ID].ide_devcon & 2) + return 0; + if (idedrive[PCMCIA_IDE_ID * 2]->irq) + return GAYLE_IRQ_BSY; + return 0; +} + +static uae_u8 checkgayleideirq (void) { int i; if (!idedrive) @@ -231,7 +262,7 @@ static int isideirq (void) /* IDE killer feature. Do not eat interrupt to make booting faster. */ if (idedrive[i]->irq && idedrive[i]->hdhfd.size == 0) idedrive[i]->irq = 0; - return 1; + return GAYLE_IRQ_IDE; } } return 0; @@ -244,16 +275,16 @@ void rethink_gayle (void) uae_u8 mask; if (currprefs.cs_ide == IDE_A4000) { - if (isideirq ()) - gayle_irq |= GAYLE_IRQ_IDE; + gayle_irq |= checkgayleideirq (); if ((gayle_irq & GAYLE_IRQ_IDE) && !(intreq & 0x0008)) INTREQ_0 (0x8000 | 0x0008); + return; } if (currprefs.cs_ide != IDE_A600A1200 && !currprefs.cs_pcmcia) return; - if (isideirq ()) - gayle_irq |= GAYLE_IRQ_IDE; + gayle_irq |= checkgayleideirq (); + gayle_irq |= checkpcmciaideirq (); mask = gayle_int & gayle_irq; if (mask & (GAYLE_IRQ_IDE | GAYLE_IRQ_WR)) lev2 = 1; @@ -290,7 +321,7 @@ static void gayle_cs_change (uae_u8 mask, int onoff) if (changed) { gayle_irq |= mask; rethink_gayle (); - if (mask & GAYLE_CS_CCDET) { + if ((mask & GAYLE_CS_CCDET) && (gayle_irq & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)) != (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)) { if (gayle_irq & GAYLE_IRQ_RESET) uae_reset (0); if (gayle_irq & GAYLE_IRQ_BERR) @@ -329,7 +360,9 @@ static uae_u8 read_gayle_cfg (void) } static void write_gayle_irq (uae_u8 val) { - gayle_irq = (gayle_irq & val) | (val & 3); + gayle_irq = (gayle_irq & val) | (val & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)); + if ((gayle_irq & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)) == (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)) + pcmcia_reset (); } static uae_u8 read_gayle_irq (void) { @@ -363,8 +396,8 @@ static uae_u8 read_gayle_cs (void) uae_u8 v; v = gayle_cs_mask | gayle_cs; - if (isideirq ()) - v |= GAYLE_CS_IDE; + v |= checkgayleideirq (); + v |= checkpcmciaideirq (); return v; } @@ -388,7 +421,7 @@ static void ide_interrupt_do (struct ide_hdf *ide) static void ide_fail_err (uae_u8 err) { ide->regs->ide_error |= err; - if (ide_drv == 1 && idedrive[ide2 + 1]->hdhfd.size == 0) + if (ide->regs->ide_drv == 1 && idedrive[ide2 + 1]->hdhfd.size == 0) idedrive[ide2]->status |= IDE_STATUS_ERR; ide->status |= IDE_STATUS_ERR; ide_interrupt (); @@ -457,7 +490,7 @@ static void ide_identify_drive (void) totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack; pw (57, (uae_u16)totalsecs); pw (58, (uae_u16)(totalsecs >> 16)); - v = idedrive[ide_drv]->multiple_mode; + v = idedrive[ide->regs->ide_drv]->multiple_mode; pw (59, (v > 0 ? 0x100 : 0) | v); totalsecs = ide->hdhfd.size / ide->blocksize; if (totalsecs > 0x0fffffff) @@ -860,7 +893,7 @@ static void ide_put_data (uae_u16 v) ide_interrupt (); } -static int get_ide_reg (uaecptr addr) +static int get_gayle_ide_reg (uaecptr addr) { uaecptr a = addr; addr &= 0xffff; @@ -875,51 +908,20 @@ static int get_ide_reg (uaecptr addr) addr &= ~0x400; } } - ide = idedrive[ide_drv + ide2]; + ide = idedrive[ide2]; + if (ide->regs->ide_drv) + ide = idedrive[ide2 + 1]; return addr; } -static uae_u32 ide_read (uaecptr addr) +static uae_u32 ide_read_reg (int ide_reg) { - int ide_reg; uae_u8 v = 0; - addr &= 0xffff; - if ((IDE_LOG > 2 && (addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)) || IDE_LOG > 4) - write_log (L"IDE_READ %08X PC=%X\n", addr, M68K_GETPC); - if (currprefs.cs_ide <= 0) { - if (addr == 0x201c) // AR1200 IDE detection hack - return 0x7f; - return 0xff; - } - if (addr >= GAYLE_IRQ_4000 && addr <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == IDE_A4000) { - uae_u8 v = gayle_irq; - gayle_irq = 0; - return v; - } - if (addr >= 0x4000) { - if (addr == GAYLE_IRQ_1200) { - if (currprefs.cs_ide == IDE_A600A1200) - return read_gayle_irq (); - return 0; - } else if (addr == GAYLE_INT_1200) { - if (currprefs.cs_ide == IDE_A600A1200) - return read_gayle_int (); - return 0; - } - return 0; - } - ide_reg = get_ide_reg (addr); - /* Emulated "ide killer". Prevents long KS boot delay if no drives installed */ - if (idedrive[0]->hdhfd.size == 0 && idedrive[2]->hdhfd.size == 0) { - if (ide_reg == IDE_STATUS) - return 0x7f; - return 0xff; - } switch (ide_reg) { case IDE_DRVADDR: - v = ((ide_drv ? 2 : 1) | ((ide->regs->ide_select & 15) << 2)) ^ 0xff; + v = ((ide->regs->ide_drv ? 2 : 1) | ((ide->regs->ide_select & 15) << 2)) ^ 0xff; break; case IDE_DATA: break; @@ -972,27 +974,8 @@ static uae_u32 ide_read (uaecptr addr) return v; } -static void ide_write (uaecptr addr, uae_u32 val) +static void ide_write_reg (int ide_reg, uae_u32 val) { - int ide_reg; - - if ((IDE_LOG > 2 && (addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)) || IDE_LOG > 4) - write_log (L"IDE_WRITE %08X=%02X PC=%X\n", addr, (uae_u32)val & 0xff, M68K_GETPC); - if (currprefs.cs_ide <= 0) - return; - if (currprefs.cs_ide == IDE_A600A1200) { - if (addr == GAYLE_IRQ_1200) { - write_gayle_irq (val); - return; - } - if (addr == GAYLE_INT_1200) { - write_gayle_int (val); - return; - } - } - if (addr >= 0x4000) - return; - ide_reg = get_ide_reg (addr); ide->regs->ide_devcon &= ~0x80; /* clear HOB */ if (IDE_LOG > 2 && ide_reg > 0) write_log (L"IDE%d register %d=%02X\n", ide->num, ide_reg, (uae_u32)val & 0xff); @@ -1029,7 +1012,7 @@ static void ide_write (uaecptr addr, uae_u32 val) break; case IDE_SELECT: ide->regs->ide_select = val; - ide_drv = (val & 0x10) ? 1 : 0; + ide->regs->ide_drv = (val & 0x10) ? 1 : 0; break; case IDE_STATUS: ide->irq = 0; @@ -1038,6 +1021,70 @@ static void ide_write (uaecptr addr, uae_u32 val) } } +static uae_u32 gayle_read2 (uaecptr addr) +{ + int ide_reg; + uae_u8 v = 0; + + addr &= 0xffff; + if ((IDE_LOG > 2 && (addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)) || IDE_LOG > 4) + write_log (L"IDE_READ %08X PC=%X\n", addr, M68K_GETPC); + if (currprefs.cs_ide <= 0) { + if (addr == 0x201c) // AR1200 IDE detection hack + return 0x7f; + return 0xff; + } + if (addr >= GAYLE_IRQ_4000 && addr <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == IDE_A4000) { + uae_u8 v = gayle_irq; + gayle_irq = 0; + return v; + } + if (addr >= 0x4000) { + if (addr == GAYLE_IRQ_1200) { + if (currprefs.cs_ide == IDE_A600A1200) + return read_gayle_irq (); + return 0; + } else if (addr == GAYLE_INT_1200) { + if (currprefs.cs_ide == IDE_A600A1200) + return read_gayle_int (); + return 0; + } + return 0; + } + ide_reg = get_gayle_ide_reg (addr); + /* Emulated "ide killer". Prevents long KS boot delay if no drives installed */ + if (idedrive[0]->hdhfd.size == 0 && idedrive[2]->hdhfd.size == 0) { + if (ide_reg == IDE_STATUS) + return 0x7f; + return 0xff; + } + return ide_read_reg (ide_reg); +} + +static void gayle_write2 (uaecptr addr, uae_u32 val) +{ + int ide_reg; + + if ((IDE_LOG > 2 && (addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)) || IDE_LOG > 4) + write_log (L"IDE_WRITE %08X=%02X PC=%X\n", addr, (uae_u32)val & 0xff, M68K_GETPC); + if (currprefs.cs_ide <= 0) + return; + if (currprefs.cs_ide == IDE_A600A1200) { + if (addr == GAYLE_IRQ_1200) { + write_gayle_irq (val); + return; + } + if (addr == GAYLE_INT_1200) { + write_gayle_int (val); + return; + } + } + if (addr >= 0x4000) + return; + ide_reg = get_gayle_ide_reg (addr); + ide_write_reg (ide_reg, val); +} + static int gayle_read (uaecptr addr) { uaecptr oaddr = addr; @@ -1074,7 +1121,7 @@ static int gayle_read (uaecptr addr) } } if (!got) - v = ide_read (addr); + v = gayle_read2 (addr); if (GAYLE_LOG) write_log (L"GAYLE_READ %08X=%02X PC=%08X\n", oaddr, (uae_u32)v & 0xff, M68K_GETPC); return v; @@ -1116,9 +1163,9 @@ static void gayle_write (uaecptr addr, int val) } if (GAYLE_LOG) - write_log (L"GAYLE_WRITE %08X=%02X PC=%08X\n", addr, (uae_u32)val & 0xff, M68K_GETPC); + write_log (L"GAYLE_WRITE %08X=%02X PC=%08X\n", oaddr, (uae_u32)val & 0xff, M68K_GETPC); if (!got) - ide_write (addr, val); + gayle_write2 (addr, val); } static uae_u32 REGPARAM3 gayle_lget (uaecptr) REGPARAM; @@ -1165,7 +1212,7 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr) addr -= NCR_OFFSET; return (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1); } - ide_reg = get_ide_reg (addr); + ide_reg = get_gayle_ide_reg (addr); if (ide_reg == IDE_DATA) return ide_get_data (); v = gayle_bget (addr) << 8; @@ -1204,7 +1251,7 @@ static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value) ncr_bput2 (addr + 1, value); return; } - ide_reg = get_ide_reg (addr); + ide_reg = get_gayle_ide_reg (addr); if (ide_reg == IDE_DATA) { ide_put_data (value); return; @@ -1461,7 +1508,7 @@ void gayle_hsync (void) { int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < TOTAL_IDE * 2; i++) { struct ide_hdf *ide = idedrive[i]; if (ide->irq_delay > 0) { ide->irq_delay--; @@ -1471,12 +1518,71 @@ void gayle_hsync (void) } } +static void alloc_ide_mem (struct ide_hdf **ide, int max) +{ + int i; + + for (i = 0; i < max; i++) { + if (!ide[i]) + ide[i] = xcalloc (struct ide_hdf, 1); + } +} + +static struct ide_hdf *add_ide_unit (int ch, const TCHAR *path, int blocksize, int readonly, + const TCHAR *devname, int sectors, int surfaces, int reserved, + int bootpri, TCHAR *filesys) +{ + struct ide_hdf *ide; + + alloc_ide_mem (idedrive, TOTAL_IDE * 2); + ide = idedrive[ch]; + if (!hdf_hd_open (&ide->hdhfd, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys)) + return NULL; + ide->blocksize = blocksize; + ide->lba48 = ide->hdhfd.size >= 128 * (uae_u64)0x40000000 ? 1 : 0; + ide->status = 0; + ide->data_offset = 0; + ide->data_size = 0; + return ide; +} + static int pcmcia_common_size, pcmcia_attrs_size; static int pcmcia_common_mask; static uae_u8 *pcmcia_common; static uae_u8 *pcmcia_attrs; static int pcmcia_write_min, pcmcia_write_max; +static int get_pcmcmia_ide_reg (uaecptr addr) +{ + int reg; + + addr &= 0x80000 - 1; + if (addr < 0x20000) + return -1; /* attribute */ + if (addr >= 0x40000) + return -1; + addr -= 0x20000; + reg = addr & 15; + ide = idedrive[PCMCIA_IDE_ID * 2]; + if (ide->regs->ide_drv) + ide = idedrive[PCMCIA_IDE_ID * 2 + 1]; + if (reg < 8) + return reg; + if (reg == 8) + reg = IDE_DATA; + else if (reg == 9) + reg = IDE_DATA; + else if (reg == 13) + reg = IDE_ERROR; + else if (reg == 14) + reg = IDE_DEVCON; + else if (reg == 15) + reg = IDE_DRVADDR; + else + reg = -1; + return reg; +} + static uae_u32 gayle_attr_read (uaecptr addr) { uae_u8 v = 0; @@ -1491,9 +1597,31 @@ static uae_u32 gayle_attr_read (uaecptr addr) } if (addr >= pcmcia_attrs_size) return v; + if (pcmcia_type == PCMCIA_IDE) { + if (addr >= 0x200 && addr < 0x200 + sizeof (pcmcia_configuration) * 2) { + int offset = (addr - 0x200) / 2; + return pcmcia_configuration[offset]; + } + if (pcmcia_configured) { + int reg = get_pcmcmia_ide_reg (addr); + if (reg >= 0) { + if (reg == 0) { + static uae_u16 data; + if (addr < 0x30000) + data = ide_get_data (); + else + return data & 0xff; + return (data >> 8) & 0xff; + } else { + return ide_read_reg (reg); + } + } + } + } v = pcmcia_attrs[addr / 2]; return v; } + static void gayle_attr_write (uaecptr addr, uae_u32 v) { if (PCMCIA_LOG > 1) @@ -1501,12 +1629,134 @@ static void gayle_attr_write (uaecptr addr, uae_u32 v) addr &= 0x80000 - 1; if (addr >= 0x40000) { if (PCMCIA_LOG > 0) - write_log (L"GAYLE: Reset active\n"); + write_log (L"GAYLE: Reset enabled\n"); + pcmcia_reset (); } else if (addr < pcmcia_attrs_size) { - ; + if (pcmcia_type == PCMCIA_IDE) { + if (addr >= 0x200 && addr < 0x200 + sizeof (pcmcia_configuration) * 2) { + int offset = (addr - 0x200) / 2; + pcmcia_configuration[offset] = v; + if (offset == 0) { + if (v & 0x80) { + pcmcia_reset (); + } else { + write_log (L"PCMCIA IO configured = %02x\n", v); + if ((v & 0x3f) != 1) + write_log (L"WARNING: Only config index 1 is emulated!\n"); + pcmcia_configured = true; + } + } + } + if (pcmcia_configured) { + int reg = get_pcmcmia_ide_reg (addr); + if (reg >= 0) { + if (reg == 0) { + static uae_u16 data; + if (addr >= 0x30000) { + data = (v & 0xff) << 8; + } else { + data |= v & 0xff; + ide_put_data (data); + } + return; + } + ide_write_reg (reg, v); + } + } + } } } +static void initscideattr (int readonly) +{ + uae_u8 *rp; + uae_u8 *p = pcmcia_attrs; + struct hardfiledata *hfd = &pcmcia_sram->hfd; + + /* Mostly just copied from real CF cards.. */ + + /* CISTPL_DEVICE */ + *p++ = 0x01; + *p++ = 0x04; + *p++ = 0xdf; + *p++ = 0x4a; + *p++ = 0x01; + *p++ = 0xff; + + /* CISTPL_DEVICEOC */ + *p++ = 0x1c; + *p++ = 0x04; + *p++ = 0x02; + *p++ = 0xd9; + *p++ = 0x01; + *p++ = 0xff; + + /* CISTPL_JEDEC */ + *p++ = 0x18; + *p++ = 0x02; + *p++ = 0xdf; + *p++ = 0x01; + + /* CISTPL_VERS_1 */ + *p++= 0x15; + rp = p++; + *p++= 4; /* PCMCIA 2.1 */ + *p++= 1; + strcpy ((char*)p, "UAE"); + p += strlen ((char*)p) + 1; + strcpy ((char*)p, "68000"); + p += strlen ((char*)p) + 1; + strcpy ((char*)p, "Generic Emulated PCMCIA IDE"); + p += strlen ((char*)p) + 1; + *p++= 0xff; + *rp = p - rp - 1; + + /* CISTPL_FUNCID */ + *p++ = 0x21; + *p++ = 0x02; + *p++ = 0x04; + *p++ = 0x01; + + /* CISTPL_FUNCE */ + *p++ = 0x22; + *p++ = 0x02; + *p++ = 0x01; + *p++ = 0x01; + + /* CISTPL_FUNCE */ + *p++ = 0x22; + *p++ = 0x03; + *p++ = 0x02; + *p++ = 0x0c; + *p++ = 0x0f; + + /* CISTPL_CONFIG */ + *p++ = 0x1a; + *p++ = 0x05; + *p++ = 0x01; + *p++ = 0x01; + *p++ = 0x00; + *p++ = 0x02; + *p++ = 0x0f; + + /* CISTPL_CFTABLEENTRY */ + *p++ = 0x1b; + *p++ = 0x06; + *p++ = 0xc0; + *p++ = 0x01; + *p++ = 0x21; + *p++ = 0xb5; + *p++ = 0x1e; + *p++ = 0x4d; + + /* CISTPL_NO_LINK */ + *p++ = 0x14; + *p++ = 0x00; + + /* CISTPL_END */ + *p++ = 0xff; +} + static void initsramattr (int size, int readonly) { uae_u8 *rp; @@ -1560,9 +1810,8 @@ static void initsramattr (int size, int readonly) p += strlen ((char*)p) + 1; sprintf ((char*)p, "Generic Emulated %dKB PCMCIA SRAM Card", size >> 10); p += strlen ((char*)p) + 1; - *p++= 0; *p++= 0xff; - *rp = p - rp; + *rp = p - rp - 1; /* CISTPL_FUNCID */ *p++ = 0x21; @@ -1626,6 +1875,8 @@ static int freepcmcia (int reset) } if (pcmcia_card) gayle_cs_change (GAYLE_CS_CCDET, 0); + + pcmcia_reset (); pcmcia_card = 0; xfree (pcmcia_common); @@ -1640,7 +1891,7 @@ static int freepcmcia (int reset) return 1; } -static int initpcmcia (const TCHAR *path, int readonly, int reset) +static int initpcmcia (const TCHAR *path, int readonly, int type, int reset) { if (currprefs.cs_pcmcia == 0) return 0; @@ -1649,34 +1900,61 @@ static int initpcmcia (const TCHAR *path, int readonly, int reset) pcmcia_sram = xcalloc (struct hd_hardfiledata, 1); if (!pcmcia_sram->hfd.handle_valid) reset = 1; - if (reset) { - if (path) - hdf_hd_open (pcmcia_sram, path, 512, readonly, NULL, 0, 0, 0, 0, NULL); - } else { - pcmcia_sram->hfd.drive_empty = 0; - } - if (pcmcia_sram->hfd.readonly) - readonly = 1; - pcmcia_common_size = 0; - pcmcia_readonly = readonly; - pcmcia_attrs_size = 256; - pcmcia_attrs = xcalloc (uae_u8, pcmcia_attrs_size); - if (!pcmcia_sram->hfd.drive_empty) { - pcmcia_common_size = pcmcia_sram->hfd.virtsize; - if (pcmcia_sram->hfd.virtsize > 4 * 1024 * 1024) { - write_log (L"PCMCIA SRAM: too large device, %d bytes\n", pcmcia_sram->hfd.virtsize); - pcmcia_common_size = 4 * 1024 * 1024; + + if (type == PCMCIA_SRAM) { + if (reset) { + if (path) + hdf_hd_open (pcmcia_sram, path, 512, readonly, NULL, 0, 0, 0, 0, NULL); + } else { + pcmcia_sram->hfd.drive_empty = 0; } - pcmcia_common = xcalloc (uae_u8, pcmcia_common_size); - write_log (L"PCMCIA SRAM: '%s' open, size=%d\n", path, pcmcia_common_size); - hdf_read (&pcmcia_sram->hfd, pcmcia_common, 0, pcmcia_common_size); + + if (pcmcia_sram->hfd.readonly) + readonly = 1; + pcmcia_common_size = 0; + pcmcia_readonly = readonly; + pcmcia_attrs_size = 256; + pcmcia_attrs = xcalloc (uae_u8, pcmcia_attrs_size); + pcmcia_type = type; + + if (!pcmcia_sram->hfd.drive_empty) { + pcmcia_common_size = pcmcia_sram->hfd.virtsize; + if (pcmcia_sram->hfd.virtsize > 4 * 1024 * 1024) { + write_log (L"PCMCIA SRAM: too large device, %d bytes\n", pcmcia_sram->hfd.virtsize); + pcmcia_common_size = 4 * 1024 * 1024; + } + pcmcia_common = xcalloc (uae_u8, pcmcia_common_size); + write_log (L"PCMCIA SRAM: '%s' open, size=%d\n", path, pcmcia_common_size); + hdf_read (&pcmcia_sram->hfd, pcmcia_common, 0, pcmcia_common_size); + pcmcia_card = 1; + initsramattr (pcmcia_common_size, readonly); + if (!(gayle_cs & GAYLE_CS_DIS)) { + gayle_map_pcmcia (); + card_trigger (1); + } + } + } else if (type == PCMCIA_IDE) { + + if (reset) { + if (path) + add_ide_unit (PCMCIA_IDE_ID * 2, path, 512, readonly, NULL, 0, 0, 0, 0, NULL); + } + + pcmcia_common_size = 0; + pcmcia_readonly = readonly; + pcmcia_attrs_size = 0x40000; + pcmcia_attrs = xcalloc (uae_u8, pcmcia_attrs_size); + pcmcia_type = type; + + write_log (L"PCMCIA IDE: '%s' open\n", path); pcmcia_card = 1; - initsramattr (pcmcia_common_size, readonly); + initscideattr (readonly); if (!(gayle_cs & GAYLE_CS_DIS)) { gayle_map_pcmcia (); card_trigger (1); } } + pcmcia_write_min = -1; pcmcia_write_max = -1; return 1; @@ -1695,6 +1973,7 @@ static uae_u32 gayle_common_read (uaecptr addr) v = pcmcia_common[addr]; return v; } + static void gayle_common_write (uaecptr addr, uae_u32 v) { if (PCMCIA_LOG > 2) @@ -1774,6 +2053,15 @@ static uae_u32 REGPARAM2 gayle_attr_wget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + + if (pcmcia_type == PCMCIA_IDE && pcmcia_configured) { + int reg = get_pcmcmia_ide_reg (addr); + if (reg == IDE_DATA) { + // 16-bit register + return ide_get_data (); + } + } + v = gayle_attr_bget (addr) << 8; v |= gayle_attr_bget (addr + 1); return v; @@ -1798,6 +2086,16 @@ static void REGPARAM2 gayle_attr_wput (uaecptr addr, uae_u32 value) #ifdef JIT special_mem |= S_WRITE; #endif + + if (pcmcia_type == PCMCIA_IDE && pcmcia_configured) { + int reg = get_pcmcmia_ide_reg (addr); + if (reg == IDE_DATA) { + // 16-bit register + ide_put_data (value); + return; + } + } + gayle_attr_bput (addr, value >> 8); gayle_attr_bput (addr + 1, value & 0xff); } @@ -1885,7 +2183,7 @@ void gayle_free_units (void) { int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < TOTAL_IDE * 2; i++) { struct ide_hdf *ide = idedrive[i]; if (ide) { hdf_hd_close (&ide->hdhfd); @@ -1895,16 +2193,6 @@ void gayle_free_units (void) freepcmcia (1); } -static void alloc_ide_mem (struct ide_hdf **ide, int max) -{ - int i; - - for (i = 0; i < max; i++) { - if (!ide[i]) - ide[i] = xcalloc (struct ide_hdf, 1); - } -} - #if 0 #include "zfile.h" static void dumphdf (struct hardfiledata *hfd) @@ -1931,19 +2219,13 @@ int gayle_add_ide_unit (int ch, TCHAR *path, int blocksize, int readonly, { struct ide_hdf *ide; - if (ch >= 4) - return -1; - alloc_ide_mem (idedrive, 4); - ide = idedrive[ch]; - if (!hdf_hd_open (&ide->hdhfd, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys)) + if (ch >= 2 * 2) return -1; - ide->blocksize = blocksize; - ide->lba48 = ide->hdhfd.size >= 128 * (uae_u64)0x40000000 ? 1 : 0; + ide = add_ide_unit (ch, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys); + if (ide == NULL) + return 0; write_log (L"GAYLE_IDE%d '%s', CHS=%d,%d,%d. %uM. LBA48=%d\n", ch, path, ide->hdhfd.cyls, ide->hdhfd.heads, ide->hdhfd.secspertrack, (int)(ide->hdhfd.size / (1024 * 1024)), ide->lba48); - ide->status = 0; - ide->data_offset = 0; - ide->data_size = 0; ide->type = IDE_GAYLE; //dumphdf (&ide->hdhfd.hfd); return 1; @@ -1951,13 +2233,26 @@ int gayle_add_ide_unit (int ch, TCHAR *path, int blocksize, int readonly, int gayle_add_pcmcia_sram_unit (const TCHAR *path, int readonly) { - return initpcmcia (path, readonly, 1); + return initpcmcia (path, readonly, PCMCIA_SRAM, 1); +} + +int gayle_add_pcmcia_ide_unit (const TCHAR *path, int readonly) +{ + return initpcmcia (path, readonly, PCMCIA_IDE, 1); } int gayle_modify_pcmcia_sram_unit (const TCHAR *path, int readonly, int insert) { if (insert) - return initpcmcia (path, readonly, pcmcia_sram ? 0 : 1); + return initpcmcia (path, readonly, PCMCIA_SRAM, pcmcia_sram ? 0 : 1); + else + return freepcmcia (0); +} + +int gayle_modify_pcmcia_ide_unit (const TCHAR *path, int readonly, int insert) +{ + if (insert) + return initpcmcia (path, readonly, PCMCIA_IDE, pcmcia_sram ? 0 : 1); else return freepcmcia (0); } @@ -1966,10 +2261,10 @@ static void initide (void) { int i; - alloc_ide_mem (idedrive, 4); + alloc_ide_mem (idedrive, TOTAL_IDE * 2); if (isrestore ()) return; - for (i = 0; i < 2; i++) { + for (i = 0; i < TOTAL_IDE; i++) { ideregs[i].ide_error = 1; ideregs[i].ide_sector = ideregs[i].ide_nsector = 1; ideregs[i].ide_select = 0; @@ -1977,13 +2272,12 @@ static void initide (void) idedrive[i * 2 + 0]->regs = &ideregs[i]; idedrive[i * 2 + 1]->regs = &ideregs[i]; } - ide_drv = 0; ide_splitter = 0; if (idedrive[2]->hdhfd.size) { ide_splitter = 1; write_log (L"IDE splitter enabled\n"); } - for (i = 0; i < 4; i++) + for (i = 0; i < TOTAL_IDE * 2; i++) idedrive[i]->num = i; gayle_irq = gayle_int = 0; } @@ -2047,7 +2341,7 @@ uae_u8 *save_ide (int num, int *len, uae_u8 *dstptr) uae_u8 *dstbak, *dst; struct ide_hdf *ide; - if (idedrive[num] == NULL) + if (num >= TOTAL_IDE * 2 || idedrive[num] == NULL) return NULL; if (currprefs.cs_ide <= 0) return NULL; @@ -2096,7 +2390,7 @@ uae_u8 *restore_ide (uae_u8 *src) TCHAR *path; struct ide_hdf *ide; - alloc_ide_mem (idedrive, 4); + alloc_ide_mem (idedrive, TOTAL_IDE * 2); num = restore_u32 (); ide = idedrive[num]; size = restore_u64 (); diff --git a/hardfile.cpp b/hardfile.cpp index c209b567..f47f8dae 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -1367,8 +1367,10 @@ void hardfile_do_disk_change (struct uaedev_config_info *uci, int insert) if (uci->controller == HD_CONTROLLER_PCMCIA_SRAM) { gayle_modify_pcmcia_sram_unit (uci->rootdir, uci->readonly, insert); return; + } else if (uci->controller == HD_CONTROLLER_PCMCIA_IDE) { + gayle_modify_pcmcia_ide_unit (uci->rootdir, uci->readonly, insert); + return; } - hfd = get_hardfile_data (fsid); if (!hfd) return; diff --git a/include/gayle.h b/include/gayle.h index 695aeb8c..cf154ce6 100644 --- a/include/gayle.h +++ b/include/gayle.h @@ -5,7 +5,9 @@ extern int gayle_add_ide_unit (int ch, TCHAR *path, int blocksize, int readonly, TCHAR *devname, int sectors, int surfaces, int reserved, int bootpri, TCHAR *filesys); extern int gayle_modify_pcmcia_sram_unit (const TCHAR *path, int readonly, int insert); +extern int gayle_modify_pcmcia_ide_unit (const TCHAR *path, int readonly, int insert); extern int gayle_add_pcmcia_sram_unit (const TCHAR *path, int readonly); +extern int gayle_add_pcmcia_ide_unit (const TCHAR *path, int readonly); extern void gayle_free_units (void); extern void rethink_gayle (void); extern void gayle_map_pcmcia (void); diff --git a/main.cpp b/main.cpp index 9a68e099..80c47d93 100644 --- a/main.cpp +++ b/main.cpp @@ -236,9 +236,9 @@ void fixup_prefs (struct uae_prefs *p) err = 1; } - if (p->address_space_24 && (p->gfxmem_size != 0 || p->z3fastmem_size != 0)) { - p->z3fastmem_size = p->gfxmem_size = 0; - write_log (L"Can't use a graphics card or Zorro III fastmem when using a 24 bit\n" + if (p->address_space_24 && (p->gfxmem_size != 0 || p->z3fastmem_size != 0 || p->z3fastmem2_size != 0 || p->z3chipmem_size != 0)) { + p->z3fastmem_size = p->z3fastmem2_size = p->gfxmem_size = p->z3chipmem_size = 0; + write_log (L"Can't use a graphics card or 32-bit memory when using a 24 bit\n" L"address space - sorry.\n"); } if (p->bogomem_size != 0 && p->bogomem_size != 0x80000 && p->bogomem_size != 0x100000 && p->bogomem_size != 0x180000 && p->bogomem_size != 0x1c0000) { diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 4425cc53..89f28729 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -97,6 +97,7 @@ extern int log_a2065, a2065_promiscuous; extern bool rawinput_enabled_hid; int log_scsi; int log_net; +int log_vsync; int uaelib_debug; int pissoff_value = 25000; unsigned int fpucontrol; @@ -4601,6 +4602,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) log_uaeserial = 1; return 1; } + if (!_tcscmp (arg, L"vsynclog")) { + log_vsync = 1; + return 1; + } if (!_tcscmp (arg, L"clipboarddebug")) { clipboard_debug = 1; return 1; diff --git a/od-win32/win32.h b/od-win32/win32.h index 64ea6d2b..98f82df3 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,8 +19,8 @@ #define LANG_DLL 1 //#define WINUAEBETA L"" -#define WINUAEBETA L"Beta 1" -#define WINUAEDATE MAKEBD(2011, 11, 26) +#define WINUAEBETA L"Beta 2" +#define WINUAEDATE MAKEBD(2011, 12, 4) #define WINUAEEXTRA L"" #define WINUAEREV L"" @@ -120,7 +120,7 @@ extern void send_tablet_proximity (int); void addnotifications (HWND hwnd, int remove, int isgui); int win32_hardfile_media_change (const TCHAR *drvname, int inserted); -extern int CheckRM (TCHAR *DriveName); +extern int CheckRM (const TCHAR *DriveName); void systray (HWND hwnd, int remove); void systraymenu (HWND hwnd); void exit_gui (int); diff --git a/od-win32/win32_filesys.cpp b/od-win32/win32_filesys.cpp index b663930f..bd8b7662 100644 --- a/od-win32/win32_filesys.cpp +++ b/od-win32/win32_filesys.cpp @@ -1,7 +1,7 @@ /* Determines if this drive-letter currently has a disk inserted */ -int CheckRM (TCHAR *DriveName) +int CheckRM (const TCHAR *DriveName) { TCHAR filename[MAX_DPATH]; DWORD dwHold; @@ -16,9 +16,9 @@ int CheckRM (TCHAR *DriveName) /* This function makes sure the volume-name being requested is not already in use, or any of the following illegal values: */ -static TCHAR *illegal_volumenames[] = { L"SYS", L"DEVS", L"LIBS", L"FONTS", L"C", L"L", L"S" }; +static const TCHAR *illegal_volumenames[] = { L"SYS", L"DEVS", L"LIBS", L"FONTS", L"C", L"L", L"S" }; -static int valid_volumename (struct uaedev_mount_info *mountinfo, TCHAR *volumename, int fullcheck) +static int valid_volumename (struct uaedev_mount_info *mountinfo, const TCHAR *volumename, int fullcheck) { int i, result = 1, illegal_count = sizeof (illegal_volumenames) / sizeof(TCHAR*); for (i = 0; i < illegal_count; i++) { diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 3656d6e2..445f8392 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -80,6 +80,8 @@ static int vblscale (int v) static int o; int n, v2; + if (!isnativevidbuf ()) + return v; n = (beamcon0 & 0x80) + maxvpos_nom; if (n != o) cleartemp = 1; diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index c131ba3e..061b4502 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1327,6 +1327,7 @@ int check_prefs_changed_gfx (void) c |= currprefs.gfx_resolution != changed_prefs.gfx_resolution ? (128) : 0; c |= currprefs.gfx_vresolution != changed_prefs.gfx_vresolution ? (128) : 0; c |= currprefs.gfx_scanlines != changed_prefs.gfx_scanlines ? (2 | 8) : 0; + c |= currprefs.monitoremu != changed_prefs.monitoremu ? (2 | 8) : 0; c |= currprefs.gfx_lores_mode != changed_prefs.gfx_lores_mode ? (2 | 8) : 0; c |= currprefs.gfx_scandoubler != changed_prefs.gfx_scandoubler ? (2 | 8) : 0; @@ -1391,6 +1392,7 @@ int check_prefs_changed_gfx (void) currprefs.gfx_resolution = changed_prefs.gfx_resolution; currprefs.gfx_vresolution = changed_prefs.gfx_vresolution; currprefs.gfx_scanlines = changed_prefs.gfx_scanlines; + currprefs.monitoremu = changed_prefs.monitoremu; currprefs.gfx_lores_mode = changed_prefs.gfx_lores_mode; currprefs.gfx_scandoubler = changed_prefs.gfx_scandoubler; @@ -2290,6 +2292,10 @@ double vblank_calibrate (double approx_vblank, bool waitonly) return tsum; } +static int frame_missed, frame_counted, frame_errors; +static int frame_usage, frame_usage_avg, frame_usage_total; +extern int log_vsync; + bool vsync_busywait (int *freetime) { bool v; @@ -2297,22 +2303,33 @@ bool vsync_busywait (int *freetime) static bool framelost; frame_time_t t; + if (log_vsync) { + console_out_f(L"%8d %8d %3d%% (%3d%%)\r", frame_counted, frame_missed, frame_usage, frame_usage_avg); + } + *freetime = 0; - if (currprefs.turbo_emulation) + if (currprefs.turbo_emulation) { + frame_missed++; return true; + } t = read_processor_time (); if (!framelost && t - prevtime > vblankbasefull) { framelost = true; + frame_missed++; return true; } - *freetime = (t - prevtime) * 100 / vblankbasefull; - if (*freetime > 99) - *freetime = 99; - else if (*freetime < 0) - *freetime = 0; + frame_usage = (t - prevtime) * 100 / vblankbasefull; + if (frame_usage > 99) + frame_usage = 99; + else if (frame_usage < 0) + frame_usage = 0; + frame_usage_total += frame_usage; + *freetime = frame_usage; + if (frame_counted) + frame_usage_avg = frame_usage_total / frame_counted; v = false; while (!framelost && read_processor_time () - prevtime < vblankbasewait) @@ -2325,8 +2342,10 @@ bool vsync_busywait (int *freetime) } if (v) { prevtime = read_processor_time (); + frame_counted++; return true; } + frame_errors++; return false; } @@ -2939,6 +2958,10 @@ void toggle_fullscreen (int mode) HDC gethdc (void) { HDC hdc = 0; + + frame_missed = frame_counted = frame_errors = 0; + frame_usage = frame_usage_avg = frame_usage_total = 0; + #ifdef OPENGL if (OGL_isenabled ()) return OGL_getDC (0); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 86da65a2..9d27874e 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -3727,6 +3727,11 @@ void InitializeListView (HWND hDlg) _tcscpy(devname_str, L"*SCSRAM*"); _tcscpy (volname_str, L"n/a"); _tcscpy (bootpri_str, L"n/a"); + } else if (uci->controller == HD_CONTROLLER_PCMCIA_IDE) { + _tcscpy (blocksize_str, L"n/a"); + _tcscpy(devname_str, L"*SCIDE*"); + _tcscpy (volname_str, L"n/a"); + _tcscpy (bootpri_str, L"n/a"); } else if (type == FILESYS_HARDFILE) { _stprintf (blocksize_str, L"%d", uci->blocksize); _tcscpy (devname_str, uci->devname); @@ -5322,7 +5327,6 @@ static void enable_for_chipsetdlg (HWND hDlg) #endif ew (hDlg, IDC_FASTCOPPER, enable); ew (hDlg, IDC_GENLOCK, full_property_sheet); - ew (hDlg, IDC_MONITOREMU, full_property_sheet); ew (hDlg, IDC_BLITIMM, enable); if (enable == FALSE) { workprefs.immediate_blits = 0; @@ -8707,6 +8711,7 @@ static void inithdcontroller (HWND hDlg) SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)L"SCSI5"); SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)L"SCSI6"); SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)L"SCSRAM"); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)L"SC IDE"); SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, 0, 0); } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index d7041934..c3deeae8 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,65 @@ +Beta 2: + +- Adjusted horizontal positioning, full overscan was not visible. +- Clear display buffers when monitor type or refresh rate changes. +- A2024 1-plane mode brightness level fixed (DPL bits implemented) +- Fix A2024 10Hz flickering near panel borders. +- 16-bit color supported in A2024/Graffiti emulation. +- Disable audio emulation hacks if 68020 CE (previously only if 68000 CE) +- Switching from CE to non-CE on the fly froze the emulated machine in some situations until mode was switched back to CE. +- PCMCIA CF IDE emulation added ("SC IDE" controller type), originally developed for AROS m68k PCMCIA CF IDE support testing. +- Fastest possible without JIT + low latency vsync should work much better now (but probably still not good enough) + +Beta 1: + +- Number of supported serial ports, MIDI ports and sound devices increased, allocated dynamically. +- Fixed crash if more than max supported serial ports or MIDI ports found. +- Sort MIDI and serial ports alphabetically. +- Hardfile write protection has never worked, only worked when using real harddrives. +- Very old keyboard handshake emulation hack removed, now following key code won't arrive until current key + code has been handshaked properly. I guess this hack was needed when CIA emulation was not good enough. +- Parallel joystick adapter unused pin added to Input panel (spare/2nd button) World Cup 1990 parallel + port joystick adapter uses this pin. +- Gayle IDE emulation IDE doubler mode improved, both buses are now separate, supports drivers that + send command to drive on another bus when drive on other bus is still processing previous + command (Linux/NetBSD/AROS) +- Emulate disk write with enabled wordsync. Write does not start until wordsync marker has been found + on disk. Some games accidentally enable wordsync bit when writing. Previously write never started. +- Saving configuration crashed if scale mode was set to integer. +- -portable disables winuaebootlog.txt, also added -bootlog and -nobootlog parameters. +- Switching from physical CD to image or vice versa didn't send uaescsi.device change notifications +- Support added for special screen modes that can have different "input" and "output" resolutions + or positioning. On the fly switching also supported. +- A2024 and Graffiti emulation implemented, uses above system. Configuration in chipset panel, + autodetect = attempts to detect if mode is normal, A2024 or Graffiti. +- All programmed display modes (DBLPAL/NTSC, MULTISCAN etc..) should be always centered, exact + display positioning configuration is now taken from sync position custom registers. +- Normal modes may also have better centering without extra configuration. +- Mode switching can leave old graphics garbage, this will be fixed later. + +A2024 and Graffiti emulation notes: +- 32-bit display mode required. +- Direct3D or DirectDraw + null filter mode required. (=Does not work if DirectDraw + no filter) +- Make sure display resolution (lores/hires/shres) is equal or higher than required resolution: + * A2024 10Hz: lores + * A2024 15Hz: hires (loss of every other pixel if lores) + * A2024 only tested using WB drivers (which don't use all A2024 special features) + * Graffiti lores: hires (does not work at all if lores) + * Graffiti hires (AGA required): shres (does not work at all if hires or lores) +- A2024 output resolutions: 1024x1024 (PAL), 1024x800 (NTSC), OCS chipset: 1008x1024 or 1008x800. +- Yes, weird A2024 refresh behavior is normal, single display is built from multiple frames! +- A2024 enabled but special mode line not detected: fall back to normal native display. Real + A2024 would show 8 grayscale screen. This is not (yet? Pointless feature?) emulated. + +NOTE.NOTE.NOTE.NOTE: Because display positioning has been changed: +- Remove all custom filter positioning settings first! +- Also test without enabled horizontal or vertical centering. + +NOTE2:NOTE2:NOTE2: This can also change again during beta period. It won't be compatible with old versions. + +2.3.3 + Beta 7: - do not misdetect standard adf images that have small amount of garbage data appended at the end of file diff --git a/od-win32/writelog.cpp b/od-win32/writelog.cpp index dc364bd8..42adb507 100644 --- a/od-win32/writelog.cpp +++ b/od-win32/writelog.cpp @@ -67,7 +67,7 @@ FILE *debugfile = NULL; int console_logging = 0; static int debugger_type = -1; extern BOOL debuggerinitializing; -int always_flush_log = 0; +int always_flush_log = 1; #define WRITE_LOG_BUF_SIZE 4096 diff --git a/specialmonitors.cpp b/specialmonitors.cpp index 1533e370..d05ac87b 100755 --- a/specialmonitors.cpp +++ b/specialmonitors.cpp @@ -15,6 +15,59 @@ extern unsigned int bplcon0; static uae_u8 graffiti_palette[256 * 4]; +STATIC_INLINE bool FR(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return (dataline[2] & 0x80) != 0; + else + return ((dataline[1] >> 7) & 1) != 0; +} +STATIC_INLINE bool FG(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return (dataline[1] & 0x80) != 0; + else + return ((dataline[1] >> 2) & 1) != 0; +} +STATIC_INLINE bool FB(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return (dataline[0] & 0x80) != 0; + else + return ((dataline[0] >> 4) & 1) != 0; +} +STATIC_INLINE bool FI(struct vidbuffer *src, uae_u8 *dataline) +{ + if (src->pixbytes == 4) + return (dataline[0] & 0x10) != 0; + else + return ((dataline[0] >> 1) & 1) != 0; +} + + +STATIC_INLINE void PRGB(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u8 g, uae_u8 b) +{ + if (dst->pixbytes == 4) { + dataline[0] = b; + dataline[1] = g; + dataline[2] = r; + } else { + r >>= 3; + g >>= 2; + b >>= 3; + ((uae_u16*)dataline)[0] = (r << 11) | (g << 5) | b; + } +} + +static void clearmonitor(struct vidbuffer *dst) +{ + uae_u8 *p = dst->bufmem; + for (int y = 0; y < dst->height; y++) { + memset(p, 0, dst->width * dst->pixbytes); + p += dst->rowbytes; + } +} + static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) { int y, x; @@ -30,6 +83,9 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) if (!(bplcon0 & 0x0100)) // GAUD return false; + if (monitor != MONITOREMU_GRAFFITI) + clearmonitor(dst); + command = true; found = false; isntsc = (beamcon0 & 0x20) ? 0 : 1; @@ -66,13 +122,13 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) uae_u8 mask = 0x80; uae_u8 chunky[4] = { 0, 0, 0, 0 }; while (mask) { - if (srcp[2] & 0x80) // R + if (FR(src, srcp)) // R chunky[3] |= mask; - if (srcp[1] & 0x80) // G + if (FG(src, srcp)) // G chunky[2] |= mask; - if (srcp[0] & 0x80) // B + if (FB(src, srcp)) // B chunky[1] |= mask; - if (srcp[0] & 0x10) // I + if (FI(src, srcp)) // I chunky[0] |= mask; srcp += xadd; mask >>= 1; @@ -140,23 +196,15 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) r = graffiti_palette[c * 4 + 0]; g = graffiti_palette[c * 4 + 1]; b = graffiti_palette[c * 4 + 2]; - dstp[2] = r; - dstp[1] = g; - dstp[0] = b; + PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; - dstp[2] = r; - dstp[1] = g; - dstp[0] = b; + PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; if (gfxvidinfo.xchange == 1 && !hires) { - dstp[2] = r; - dstp[1] = g; - dstp[0] = b; + PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; - dstp[2] = r; - dstp[1] = g; - dstp[0] = b; + PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; } } @@ -194,64 +242,74 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) int panel_width, panel_width_draw, panel_height, srcxoffset; bool f64, interlace, expand, wpb, less16; uae_u8 enp, dpl; - bool hires; + bool hires, ntsc, found; int idline; int total_width, total_height; - idline = currprefs.ntscmode ? 21 : 29; - - if (src->yoffset > (idline << VRES_MAX)) - return false; - dbl = gfxvidinfo.ychange == 1 ? 2 : 1; doff = (128 * 2 / gfxvidinfo.xchange) * src->pixbytes; - // min 178 max 234 - dataline = src->bufmem + (((idline << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes + (((200 << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * src->pixbytes; + found = false; + + for (idline = 21; idline <= 29; idline += 8) { + if (src->yoffset > (idline << VRES_MAX)) + continue; + // min 178 max 234 + dataline = src->bufmem + (((idline << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes + (((200 << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * src->pixbytes; #if 0 - write_log (L"%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x\n", - dataline[0 * doff + 0], dataline[0 * doff + 1], dataline[0 * doff + 2], - dataline[1 * doff + 0], dataline[1 * doff + 1], dataline[1 * doff + 2], - dataline[2 * doff + 0], dataline[2 * doff + 1], dataline[2 * doff + 2], - dataline[3 * doff + 0], dataline[3 * doff + 1], dataline[3 * doff + 2]); + write_log (L"%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x\n", + dataline[0 * doff + 0], dataline[0 * doff + 1], dataline[0 * doff + 2], + dataline[1 * doff + 0], dataline[1 * doff + 1], dataline[1 * doff + 2], + dataline[2 * doff + 0], dataline[2 * doff + 1], dataline[2 * doff + 2], + dataline[3 * doff + 0], dataline[3 * doff + 1], dataline[3 * doff + 2]); #endif + if (FB(src, &dataline[0 * doff])) // 0:B = 0 + continue; + if (!FI(src, &dataline[0 * doff])) // 0:I = 1 + continue; + if (FI(src, &dataline[2 * doff])) // 2:I = 0 + continue; + if (!FI(src, &dataline[3 * doff])) // 3:I = 1 + continue; + + ntsc = idline < 26; + found = true; + break; + } + + if (!found) + return false; + px = py = 0; - if (dataline[1 * doff + 0] & 0x80) // 1:B FN2 + if (FB(src, &dataline[1 * doff])) // 1:B FN2 px |= 2; - if (dataline[1 * doff + 1] & 0x80) // 1:G FN1 + if (FG(src, &dataline[1 * doff])) // 1:G FN1 px |= 1; - if (dataline[1 * doff + 2] & 0x80) // 1:R FN0 + if (FR(src, &dataline[1 * doff])) // 1:R FN0 py |= 1; - f64 = (dataline[0 * doff + 2] & 0x80) != 0; // 0:R - interlace = (dataline[0 * doff + 1] & 0x80) != 0; // 0:G (*Always zero) - if ((dataline[0 * doff + 0] & 0x80) != 0) // 0:B = 0 - return false; - if ((dataline[0 * doff + 0] & 0x10) == 0) // 0:I = 1 - return false; - expand = (dataline[1 * doff + 0] & 0x10) != 0; // 1:I (*Always set) - enp = (dataline[2 * doff + 2] & 0x80) ? 1 : 0; // 2:R (*ENP=3) - enp |= (dataline[2 * doff + 1] & 0x80) ? 2 : 0; // 2:G - wpb = (dataline[2 * doff + 0] & 0x80) != 0; // 2:B (*Always zero) - if ((dataline[2 * doff + 0] & 0x10) != 0) // 2:I = 0 - return false; - dpl = (dataline[3 * doff + 2] & 0x80) ? 1 : 0; // 3:R (*DPL=3) - dpl |= (dataline[3 * doff + 1] & 0x80) ? 2 : 0; // 3:G - less16 = (dataline[3 * doff + 0] & 0x80) != 0; // 3:B - if ((dataline[3 * doff + 0] & 0x10) == 0) // 3:I = 1 - return false; + f64 = FR(src, &dataline[0 * doff]) != 0; // 0:R + interlace = FG(src, &dataline[0 * doff]) != 0; // 0:G (*Always zero) + expand = FI(src, &dataline[1 * doff]) != 0; // 1:I (*Always set) + enp = FR(src, &dataline[2 * doff]) ? 1 : 0; // 2:R (*ENP=3) + enp |= FG(src, &dataline[2 * doff]) ? 2 : 0; // 2:G + wpb = FB(src, &dataline[2 * doff]) != 0; // 2:B (*Always zero) + dpl = FR(src, &dataline[3 * doff]) ? 1 : 0; // 3:R (*DPL=3) + dpl |= FG(src, &dataline[3 * doff]) ? 2 : 0; // 3:G + less16 = FB(src, &dataline[3 * doff]) != 0; // 3:B /* (*) = AOS A2024 driver static bits. Not yet implemented in emulation. */ if (f64) { panel_width = 336; - panel_width_draw = 352; + panel_width_draw = px == 2 ? 352 : 336; pxcnt = 3; hires = false; srcxoffset = 113; if (px > 2) return false; + total_width = 336 + 336 + 352; } else { panel_width = 512; panel_width_draw = 512; @@ -260,9 +318,13 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) srcxoffset = 129; if (px > 1) return false; + total_width = 512 + 512; } - panel_height = currprefs.ntscmode ? 400 : 512; + panel_height = ntsc ? 400 : 512; + if (monitor != MONITOREMU_A2024) { + clearmonitor(dst); + } #if 0 write_log (L"0 = F6-4:%d INTERLACE:%d\n", f64, interlace); @@ -279,9 +341,6 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) px, py); #endif - total_width = panel_width * (pxcnt - 1) + panel_width_draw; - if (total_width > 1024) - total_width = 1024; if (less16) { total_width -= 16; if (px == pxcnt - 1) @@ -302,29 +361,36 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) int x; for (x = 0; x < (panel_width_draw * 2) / gfxvidinfo.xchange; x++) { uae_u8 c1 = 0, c2 = 0; - if (srcp[2] & 0x80) // R + if (FR(src, srcp)) // R c1 |= 2; - if (srcp[1] & 0x80) // G + if (FG(src, srcp)) // G c2 |= 2; - if (srcp[0] & 0x80) // B + if (FB(src, srcp)) // B c1 |= 1; - if (srcp[0] & 0x10) // I + if (FI(src, srcp)) // I c2 |= 1; + if (dpl == 0) { + c1 = c2 = 0; + } else if (dpl == 1) { + c1 &= 1; + c1 |= c1 << 1; + c2 &= 1; + c2 |= c2 << 1; + } else if (dpl == 2) { + c1 &= 2; + c1 |= c1 >> 1; + c2 &= 2; + c2 |= c2 >> 1; + } if (dbl == 1) { c1 = (c1 + c2 + 1) / 2; c1 = (c1 << 6) | (c1 << 4) | (c1 << 2); - dstp1[0] = c1; - dstp1[1] = c1; - dstp1[2] = c1; + PRGB(dst, dstp1, c1, c1, c1); } else { c1 = (c1 << 6) | (c1 << 4) | (c1 << 2); c2 = (c2 << 6) | (c2 << 4) | (c2 << 2); - dstp1[0] = c1; - dstp1[1] = c1; - dstp1[2] = c1; - dstp2[0] = c2; - dstp2[1] = c2; - dstp2[2] = c2; + PRGB(dst, dstp1, c1, c1, c1); + PRGB(dst, dstp2, c2, c2, c2); dstp2 += dst->pixbytes; } srcp += src->pixbytes; @@ -350,7 +416,7 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) if (monitor != MONITOREMU_A2024) { monitor = MONITOREMU_A2024; - write_log (L"A2024 %dHz mode\n", hires ? 10 : 15); + write_log (L"A2024 %dHz %s mode\n", hires ? 10 : 15, ntsc ? L"NTSC" : L"PAL"); } return true; @@ -358,9 +424,6 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) static bool emulate_specialmonitors2(struct vidbuffer *src, struct vidbuffer *dst) { - if (src->pixbytes != 4) - return false; - if (currprefs.monitoremu == MONITOREMU_AUTO) { automatic = true; bool v = a2024(src, dst); @@ -382,6 +445,7 @@ bool emulate_specialmonitors(struct vidbuffer *src, struct vidbuffer *dst) { if (!emulate_specialmonitors2(src, dst)) { if (monitor) { + clearmonitor(dst); monitor = 0; write_log (L"Native mode\n"); } -- 2.47.3