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;
}
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];
}
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;
}
}
}
res2 = RES_MAX;
vres2 = currprefs.gfx_vresolution;
- if (islace && !vres2)
- vres2++;
if (doublescan && !islace)
vres2--;
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;
+
}
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 ();
}
} 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;
}
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;
lightpen_y1 = lightpen_y2 = -1;
reset_custom_limits ();
+
+ clearbuffer (&gfxvidinfo.drawbuffer);
+ clearbuffer (&gfxvidinfo.tempbuffer);
}
void drawing_init (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 ();
#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
{
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
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;
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)
/* 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;
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;
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)
}
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)
{
uae_u8 v;
v = gayle_cs_mask | gayle_cs;
- if (isideirq ())
- v |= GAYLE_CS_IDE;
+ v |= checkgayleideirq ();
+ v |= checkpcmciaideirq ();
return v;
}
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 ();
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)
ide_interrupt ();
}
-static int get_ide_reg (uaecptr addr)
+static int get_gayle_ide_reg (uaecptr addr)
{
uaecptr a = addr;
addr &= 0xffff;
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;
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);
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;
}
}
+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;
}
}
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;
}
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;
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;
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;
{
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--;
}
}
+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;
}
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)
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;
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;
}
if (pcmcia_card)
gayle_cs_change (GAYLE_CS_CCDET, 0);
+
+ pcmcia_reset ();
pcmcia_card = 0;
xfree (pcmcia_common);
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;
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;
v = pcmcia_common[addr];
return v;
}
+
static void gayle_common_write (uaecptr addr, uae_u32 v)
{
if (PCMCIA_LOG > 2)
#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;
#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);
}
{
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);
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)
{
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;
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);
}
{
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;
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;
}
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;
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 ();
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;
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);
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) {
extern bool rawinput_enabled_hid;
int log_scsi;
int log_net;
+int log_vsync;
int uaelib_debug;
int pissoff_value = 25000;
unsigned int fpucontrol;
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;
#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""
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);
/* 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;
/* 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++) {
static int o;
int n, v2;
+ if (!isnativevidbuf ())
+ return v;
n = (beamcon0 & 0x80) + maxvpos_nom;
if (n != o)
cleartemp = 1;
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;
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;
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;
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)
}
if (v) {
prevtime = read_processor_time ();
+ frame_counted++;
return true;
}
+ frame_errors++;
return false;
}
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);
_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);
#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;
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);
}
+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
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
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;
if (!(bplcon0 & 0x0100)) // GAUD
return false;
+ if (monitor != MONITOREMU_GRAFFITI)
+ clearmonitor(dst);
+
command = true;
found = false;
isntsc = (beamcon0 & 0x20) ? 0 : 1;
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;
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;
}
}
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;
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);
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)
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;
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;
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);
{
if (!emulate_specialmonitors2(src, dst)) {
if (monitor) {
+ clearmonitor(dst);
monitor = 0;
write_log (L"Native mode\n");
}