static bool locked_rmw_cycle;
static bool ismoves;
bool mmu_ttr_enabled;
+int mmu_atc_ways;
int mmu040_movem;
uaecptr mmu040_movem_ea;
{
if (!currprefs.cpu_cycle_exact)
return 0;
+ if (currprefs.cachesize || currprefs.m68k_speed < 0)
+ return 0;
if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68020)
return 1;
if (v & 0x8000)
return 1;
- if (currprefs.cachesize || currprefs.m68k_speed < 0)
- return 0;
if (event2_count)
return 1;
return 0;
{
setclr (&intena_internal, v);
doint ();
- int_recursive++;
- rethink_intreq ();
- int_recursive--;
}
static void send_intreq_do (uae_u32 v)
{
setclr (&intreq_internal, v);
- doint ();
int_recursive++;
rethink_intreq ();
int_recursive--;
+ doint ();
}
static void INTENA (uae_u16 v)
uae_u16 old = intena;
setclr (&intena, v);
- if (!(v & 0x8000) && old == intena)
+ if (!(v & 0x8000) && old == intena && intena == intena_internal)
return;
+
+ //write_log (_T("%04x %04x %04x %04x\n"), intena, intena_internal, intreq, intreq_internal);
+
if (use_eventmode (v)) {
+ if (old == intena && intena == intena_internal)
+ return;
event2_newevent_xx (-1, INT_PROCESSING_DELAY, v, send_intena_do);
} else {
intena_internal = intena;
intreq_internal = intreq;
if (old == intreq && old2 == intreq_internal)
return false;
- if ((v & 0x8000) || currprefs.cpu_cycle_exact)
+ if (v & 0x8000)
doint ();
return true;
}
#endif
+/* "Dangerous" blitter D-channel: Writing to memory which is also currently
+ * read by bitplane DMA
+ */
static void dcheck_is_blit_dangerous (void)
{
check_is_blit_dangerous (bplpt, bplcon0_planes, 50 << bplcon0_res);
if (hardreset) {
if (!aga_mode) {
- uae_u16 c = (currprefs.chipset_mask & CSMASK_ECS_DENISE) ? 0xfff : 0x000;
+ uae_u16 c = ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA)) ? 0xfff : 0x000;
for (i = 0; i < 32; i++) {
current_colors.color_regs_ecs[i] = c;
current_colors.acolors[i] = getxcolor (c);
visible_left_border = max_diwstop - w - (max_diwstop - min_diwstart - w) / 2;
visible_left_border &= ~((xshift (1, lores_shift)) - 1);
+#if 0
/* Would the old value be good enough? If so, leave it as it is if we want to
* be clever. */
if (currprefs.gfx_xcenter == 2) {
if (center_reset || (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32))
visible_left_border = prev_x_adjust;
}
+#endif
} else if (gfxvidinfo.drawbuffer.extrawidth) {
visible_left_border = max_diwlastword - w;
if (gfxvidinfo.drawbuffer.extrawidth > 0)
else
thisframe_y_adjust = thisframe_first_drawn_line + ((thisframe_last_drawn_line - thisframe_first_drawn_line) - max_drawn_amiga_line) / 2;
+#if 0
/* Would the old value be good enough? If so, leave it as it is if we want to
* be clever. */
if (currprefs.gfx_ycenter == 2 && thisframe_y_adjust != prev_y_adjust) {
if (center_reset || (prev_y_adjust <= thisframe_first_drawn_line && prev_y_adjust + max_drawn_amiga_line > thisframe_last_drawn_line))
thisframe_y_adjust = prev_y_adjust;
}
+#endif
}
/* Make sure the value makes sense */
if (ci->dostype) { // forced dostype?
put_long (parmpacket + 80, ci->dostype); /* dostype */
} else if (hdf_read (&uip[unit_no].hf, buf, 0, sizeof buf)) {
- uae_u32 dt = get_long (rl (buf));
+ uae_u32 dt = rl (buf);
if (dt != 0x00000000 && dt != 0xffffffff)
put_long (parmpacket + 80, dt);
}
int data_multi;
int direction; // 0 = read, 1 = write
bool intdrq;
- int lba48;
+ bool lba48;
+ bool lba48cmd;
uae_u8 multiple_mode;
int irq_delay;
int irq;
static void get_lbachs (struct ide_hdf *ide, uae_u64 *lbap, unsigned int *cyl, unsigned int *head, unsigned int *sec)
{
- if (ide->lba48 && (ide->regs.ide_select & 0x40)) {
+ if (ide->lba48 && ide->lba48cmd && (ide->regs.ide_select & 0x40)) {
uae_u64 lba;
lba = (ide->regs.ide_hcyl << 16) | (ide->regs.ide_lcyl << 8) | ide->regs.ide_sector;
lba |= ((ide->regs.ide_hcyl2 << 16) | (ide->regs.ide_lcyl2 << 8) | ide->regs.ide_sector2) << 24;
static int get_nsec (struct ide_hdf *ide)
{
- if (ide->lba48)
+ if (ide->lba48 && ide->lba48cmd)
return (ide->regs.ide_nsector == 0 && ide->regs.ide_nsector2 == 0) ? 65536 : (ide->regs.ide_nsector2 * 256 + ide->regs.ide_nsector);
else
return ide->regs.ide_nsector == 0 ? 256 : ide->regs.ide_nsector;
}
static int dec_nsec (struct ide_hdf *ide, int v)
{
- if (ide->lba48) {
+ if (ide->lba48 && ide->lba48cmd) {
uae_u16 nsec;
nsec = ide->regs.ide_nsector2 * 256 + ide->regs.ide_nsector;
ide->regs.ide_nsector -= v;
static void put_lbachs (struct ide_hdf *ide, uae_u64 lba, unsigned int cyl, unsigned int head, unsigned int sec, unsigned int inc)
{
- if (ide->lba48) {
+ if (ide->lba48 && ide->lba48cmd) {
lba += inc;
ide->regs.ide_hcyl = (lba >> 16) & 0xff;
ide->regs.ide_lcyl = (lba >> 8) & 0xff;
get_lbachs (ide, &lba, &cyl, &head, &sec);
nsec = get_nsec (ide);
if (IDE_LOG > 1)
- write_log (_T("IDE%d off=%d, nsec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 ? 48 : 28);
+ write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) {
nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize;
if (IDE_LOG > 1)
uae_u64 lba;
int multi = flags & 1;
+ ide->lba48cmd = (flags & 2) != 0;
if (multi && ide->multiple_mode == 0) {
ide_fail (ide);
return;
return;
}
if (IDE_LOG > 0)
- write_log (_T("IDE%d read off=%d, sec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 ? 48 : 28);
+ write_log (_T("IDE%d read off=%d, sec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
ide->data_multi = multi ? ide->multiple_mode : 1;
ide->data_offset = 0;
ide->data_size = nsec * ide->blocksize;
uae_u64 lba;
int multi = flags & 1;
+ ide->lba48cmd = (flags & 2) != 0;
if (multi && ide->multiple_mode == 0) {
ide_fail (ide);
return;
return;
}
if (IDE_LOG > 0)
- write_log (_T("IDE%d write off=%d, sec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 ? 48 : 28);
+ write_log (_T("IDE%d write off=%d, sec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize)
nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize;
if (nsec <= 0) {
write_log (_T("**** IDE%d command %02X\n"), ide->num, cmd);
ide->regs.ide_status &= ~ (IDE_STATUS_DRDY | IDE_STATUS_DRQ | IDE_STATUS_ERR);
ide->regs.ide_error = 0;
+ ide->lba48cmd = false;
if (ide->atapi) {
extern uae_u32 mmu_tagmask, mmu_pagemask;
extern struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_WAYS][ATC_SLOTS];
+/* Last matched ATC index, next lookup starts from this index as an optimization */
+extern int mmu_atc_ways;
+
/*
* mmu access is a 4 step process:
* if mmu is not enabled just read physical
static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write,
struct mmu_atc_line **cl)
{
- int way,index;
+ int way, i, index;
static int way_miss=0;
uae_u32 tag = (mmu_is_super | (addr >> 1)) & mmu_tagmask;
index=(addr & 0x0001E000)>>13;
else
index=(addr & 0x0000F000)>>12;
- for (way=0;way<ATC_WAYS;way++) {
+ for (i = 0; i < ATC_WAYS; i++) {
+ way = mmu_atc_ways;
// if we have this
if ((tag == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
*cl=&mmu_atc_array[data][way][index];
return false;
return true;
}
+ mmu_atc_ways++;
+ mmu_atc_ways &= (ATC_WAYS - 1);
}
// we select a random way to void
*cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data,
bool write, struct mmu_atc_line **cl)
{
- int way,index;
+ int way, i, index;
static int way_miss=0;
uae_u32 tag = ((super ? 0x80000000 : 0x00000000) | (addr >> 1)) & mmu_tagmask;
index=(addr & 0x0001E000)>>13;
else
index=(addr & 0x0000F000)>>12;
- for (way=0;way<ATC_WAYS;way++) {
+ for (i = 0; i < ATC_WAYS; i++) {
+ way = mmu_atc_ways;
// if we have this
if ((tag == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
*cl=&mmu_atc_array[data][way][index];
return false;
return true;
}
+ mmu_atc_ways++;
+ mmu_atc_ways &= (ATC_WAYS - 1);
}
// we select a random way to void
*cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
/*
* UAE - The Un*x Amiga Emulator
*
-* A4000T / A4091 NCR 53C710 SCSI (not much to see here)
+* A4000T / A4091 NCR 53C710 SCSI
*
* (c) 2007-2014 Toni Wilen
*/
if (value < z3fastmem2_bank.start + currprefs.z3fastmem2_size)
value = z3fastmem2_bank.start + currprefs.z3fastmem2_size;
}
+ if (value < 0x40000000 && max_z3fastmem >= 0x41000000)
+ value = 0x40000000;
value >>= 16;
chipmem_wput (regs.regs[11] + 0x20, value);
chipmem_wput (regs.regs[11] + 0x28, value);
ncr_bput2 (addr, b);
}
-addrbank ncr_bank = {
+static addrbank ncr_bank = {
ncr_lget, ncr_wget, ncr_bget,
ncr_lput, ncr_wput, ncr_bput,
default_xlate, default_check, NULL, _T("A4091"),
* - block 0 is zeroed
*/
-int harddrive_dangerous = 0x1234dead;
+int harddrive_dangerous; // = 0x1234dead; // test only!
int do_rdbdump;
static struct uae_driveinfo uae_drives[MAX_FILESYSTEM_UNITS];
-#if 0
+#if 1
static void fixdrive (struct hardfiledata *hfd)
{
uae_u8 data[512];
#endif
}
#endif
+ if (maxmem > max_allowed_mman)
+ max_allowed_mman = maxmem;
memstats.dwLength = sizeof(memstats);
GlobalMemoryStatus(&memstats);
#define LANG_DLL 1
#if WINUAEPUBLICBETA
-#define WINUAEBETA _T("8")
+#define WINUAEBETA _T("9")
#else
#define WINUAEBETA _T("")
#endif
-#define WINUAEDATE MAKEBD(2014, 2, 16)
+#define WINUAEDATE MAKEBD(2014, 2, 22)
#define WINUAEEXTRA _T("")
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")
#define LSI_CCNTL1_DDAC 0x08
#define LSI_CCNTL1_ZMOD 0x80
+#define LSI_SBCL_IO 0x01
+#define LSI_SBCL_CD 0x02
+#define LSI_SBCL_MSG 0x04
+#define LSI_SBCL_ATN 0x08
+#define LSI_SBCL_SEL 0x10
+#define LSI_SBCL_BSY 0x20
+#define LSI_SBCL_ACK 0x40
+#define LSI_SBCL_REQ 0x80
+
/* Enable Response to Reselection */
#define LSI_SCID_RRE 0x60
uint8_t lcrc;
uint8_t sstat2;
uint8_t dwt;
+ uint8_t sbcl;
uint8_t script_active;
} LSIState;
s->ctest0 &= ~1;
if (phase == PHASE_DI)
s->ctest0 |= 1;
+ s->sbcl &= ~LSI_SBCL_REQ;
}
static void lsi_bad_phase(LSIState *s, int out, int new_phase)
lsi_script_scsi_interrupt(s, LSI_SSTAT0_MA);
lsi_stop_script(s);
lsi_set_phase(s, new_phase);
+ s->sbcl |= LSI_SBCL_REQ;
}
s->sfbr = buf[0];
s->command_complete = 0;
- id = (s->select_tag >> 8) & 0xf;
- s->lcrc = 1 << (id & 0x7);
+ id = (s->select_tag >> 8) & 0xff;
+ s->lcrc = id; //1 << (id & 0x7);
dev = scsi_device_find(&s->bus, 0, idbitstonum(id), s->current_lun);
if (!dev) {
lsi_bad_selection(s, id);
if ((s->sstat2 & PHASE_MASK) != ((insn >> 24) & 7)) {
DPRINTF("Wrong phase got %d expected %d\n",
s->sstat2 & PHASE_MASK, (insn >> 24) & 7);
- lsi_script_scsi_interrupt(s, LSI_SSTAT0_SGE);
+ lsi_script_scsi_interrupt(s, LSI_SSTAT0_MA);
+ s->sbcl |= LSI_SBCL_REQ;
break;
}
s->dnad = addr;
if (insn & (1 << 26)) {
addr = s->dsp + sextract32(addr, 0, 24);
}
- id &= ~s->scid;
s->dnad = addr;
switch (opcode) {
case 0: /* Select */
return s->sien0;
case 0x05: /* SXFER */
return s->sxfer;
-
+ case 0x09: /* SIDL */
+ /* This is needed by the linux drivers. We currently only update it
+ during the MSG IN phase. */
+ return s->sidl;
case 0xb: /* SBCL */
- /* ??? This is not correct. However it's (hopefully) only
- used for diagnostics, so should be ok. */
- return 0;
+ /* NetBSD 1.x checks for REQ */
+ tmp = s->sstat2 & PHASE_MASK;
+ /* if phase mismatch, REQ is also active */
+ tmp |= s->sbcl;
+ if (s->socl & LSI_SOCL_ATN)
+ tmp |= LSI_SBCL_ATN;
+ return tmp;
case 0xc: /* DSTAT */
tmp = s->dstat | LSI_DSTAT_DFE;
s->dstat = 0;
s->sxfer = val;
break;
case 0x0b: /* SBCL */
+ lsi_set_phase (s, val & PHASE_MASK);
break;
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
/* Linux writes to these readonly registers on startup. */