]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2820b1
authorToni Wilen <twilen@winuae.net>
Thu, 3 Jul 2014 15:12:25 +0000 (18:12 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 3 Jul 2014 15:12:25 +0000 (18:12 +0300)
45 files changed:
a2091.cpp
audio.cpp
cdtv.cpp
cfgfile.cpp
cpummu30.cpp
custom.cpp
debug.cpp
disk.cpp
drawing.cpp
expansion.cpp
filesys.cpp
gayle.cpp
gencpu.cpp
hardfile.cpp
include/a2091.h
include/disk.h
include/filesys.h
include/fsdb.h
include/memory.h
include/ncr_scsi.h
include/options.h
include/savestate.h
include/scsi.h
main.cpp
memory.cpp
moduleripper.cpp
ncr_scsi.cpp
newcpu.cpp
od-win32/fsdb_mywin32.cpp
od-win32/hardfile_win32.cpp
od-win32/mman.cpp
od-win32/registry.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/win32.h
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
qemuvga/lsi53c895a.cpp
qemuvga/qemuuaeglue.h
qemuvga/scsi/scsi.h
rommgr.cpp
savestate.cpp
scsitape.cpp
zfile.cpp

index b51db2a0e97e01ac7888f8729034125521ed03e0..61328cc640233435cdbdadf62671a559d8af881a 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
@@ -25,6 +25,7 @@
 #include "newcpu.h"
 #include "debug.h"
 #include "scsi.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "blkdev.h"
 #include "gui.h"
@@ -33,7 +34,6 @@
 #include "autoconf.h"
 #include "cdtv.h"
 #include "savestate.h"
-#include "threaddep/thread.h"
 
 #define ROM_VECTOR 0x2000
 #define ROM_OFFSET 0x2000
 #define MSG_NOP 0x08
 #define MSG_IDENTIFY 0x80
 
-static int configured;
-static uae_u8 dmacmemory[100];
-static uae_u8 *rom;
-static int rombankswitcher, rombank;
-static int rom_size, rom_mask;
-
-static int old_dmac = 0;
-static uae_u32 dmac_istr, dmac_cntr;
-static uae_u32 dmac_dawr;
-static uae_u32 dmac_acr;
-static uae_u32 dmac_wtc;
-static int dmac_dma;
-static volatile uae_u8 sasr, scmd, auxstatus;
-static volatile int wd_used;
-static volatile int wd_phase, wd_next_phase, wd_busy, wd_data_avail;
-static volatile bool wd_selected;
-static volatile int wd_dataoffset;
-static volatile uae_u8 wd_data[32];
-
-static int superdmac;
-
-#define WD_STATUS_QUEUE 2
-static volatile int scsidelay_irq[WD_STATUS_QUEUE];
-static volatile uae_u8 scsidelay_status[WD_STATUS_QUEUE];
-static volatile int queue_index;
-
-static smp_comm_pipe requests;
-static volatile int scsi_thread_running;
+static struct wd_state wd_a2091;
+static struct wd_state wd_a2091_2;
+static struct wd_state wd_a3000;
+struct wd_state wd_cdtv;
 
-static int wd33c93_ver = 1; // A
-
-struct scsi_data *scsis[8];
-static struct scsi_data *scsi;
+static struct wd_state *wda2091[] = {
+               &wd_a2091,
+               &wd_a2091_2,
+};
 
-uae_u8 wdregs[32];
+static struct wd_state *wdscsi[] {
+               &wd_a2091,
+               &wd_a2091_2,
+               &wd_a3000,
+               &wd_cdtv,
+               NULL
+};
 
-static int isirq (void)
+static int isirq (struct wd_state *wd)
 {
-       if (superdmac) {
-               if ((dmac_cntr & SCNTR_INTEN) && (dmac_istr & (ISTR_INTS | ISTR_E_INT)))
+       if (!wd->enabled)
+               return 0;
+       if (wd->superdmac) {
+               if ((wd->dmac_cntr & SCNTR_INTEN) && (wd->dmac_istr & (ISTR_INTS | ISTR_E_INT)))
                        return 1;
        } else {
-               if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & (ISTR_INTS | ISTR_E_INT)))
+               if ((wd->dmac_cntr & CNTR_INTEN) && (wd->dmac_istr & (ISTR_INTS | ISTR_E_INT)))
                        return 1;
        }
        return 0;
@@ -226,9 +210,7 @@ static int isirq (void)
 
 void rethink_a2091 (void)
 {
-       if (currprefs.cs_cdtvscsi)
-               return;
-       if (isirq ()) {
+       if (isirq (&wd_a2091) ||isirq (&wd_a2091_2) || isirq (&wd_a3000)) {
                uae_int_requested |= 2;
 #if A2091_DEBUG > 2 || A3000_DEBUG > 2
                write_log (_T("Interrupt_RETHINK\n"));
@@ -238,119 +220,119 @@ void rethink_a2091 (void)
        }
 }
 
-static void INT2 (void)
+static void INT2 (struct wd_state *wd)
 {
-       if (currprefs.cs_cdtvscsi)
+       if (!wd->enabled)
                return;
-       if (!(auxstatus & ASR_INT))
+       if (!(wd->auxstatus & ASR_INT))
                return;
-       dmac_istr |= ISTR_INTS;
-       if (isirq ())
+       wd->dmac_istr |= ISTR_INTS;
+       if (isirq (wd))
                uae_int_requested |= 2;
 }
 
-void scsi_dmac_start_dma (void)
+void scsi_dmac_start_dma (struct wd_state *wd)
 {
 #if A3000_DEBUG > 0 || A2091_DEBUG > 0
-       write_log (_T("DMAC DMA started, ADDR=%08X, LEN=%08X words\n"), dmac_acr, dmac_wtc);
+       write_log (_T("DMAC DMA started, ADDR=%08X, LEN=%08X words\n"), wd->dmac_acr, wd->dmac_wtc);
 #endif
-       dmac_dma = 1;
+       wd->dmac_dma = 1;
 }
-void scsi_dmac_stop_dma (void)
+void scsi_dmac_stop_dma (struct wd_state *wd)
 {
-       dmac_dma = 0;
-       dmac_istr &= ~ISTR_E_INT;
+       wd->dmac_dma = 0;
+       wd->dmac_istr &= ~ISTR_E_INT;
 }
 
-static void dmac_reset (void)
+static void dmac_reset (struct wd_state *wd)
 {
 #if WD33C93_DEBUG > 0
-       if (superdmac)
+       if (wd->superdmac)
                write_log (_T("A3000 %s SCSI reset\n"), WD33C93);
        else
                write_log (_T("A2091 %s SCSI reset\n"), WD33C93);
 #endif
 }
 
-static void incsasr (int w)
+static void incsasr (struct wd_state *wd, int w)
 {
-       if (sasr == WD_AUXILIARY_STATUS || sasr == WD_DATA || sasr == WD_COMMAND)
+       if (wd->sasr == WD_AUXILIARY_STATUS || wd->sasr == WD_DATA || wd->sasr == WD_COMMAND)
                return;
-       if (w && sasr == WD_SCSI_STATUS)
+       if (w && wd->sasr == WD_SCSI_STATUS)
                return;
-       sasr++;
-       sasr &= 0x1f;
+       wd->sasr++;
+       wd->sasr &= 0x1f;
 }
 
-static void dmac_cint (void)
+static void dmac_cint (struct wd_state *wd)
 {
-       dmac_istr = 0;
+       wd->dmac_istr = 0;
        rethink_a2091 ();
 }
 
-static void doscsistatus (uae_u8 status)
+static void doscsistatus (struct wd_state *wd, uae_u8 status)
 {
-       wdregs[WD_SCSI_STATUS] = status;
-       auxstatus |= ASR_INT;
+       wd->wdregs[WD_SCSI_STATUS] = status;
+       wd->auxstatus |= ASR_INT;
 #if WD33C93_DEBUG > 1
        write_log (_T("%s STATUS=%02X\n"), WD33C93, status);
 #endif
-       if (currprefs.cs_cdtvscsi) {
+       if (!wd->enabled)
+               return;
+       if (wd->cdtv) {
                cdtv_scsi_int ();
                return;
        }
-       if (!currprefs.a2091 && currprefs.cs_mbdmac != 1)
-               return;
-       INT2();
+       INT2(wd);
 #if A2091_DEBUG > 2 || A3000_DEBUG > 2
        write_log (_T("Interrupt\n"));
 #endif
 }
 
-static void set_status (uae_u8 status, int delay)
+static void set_status (struct wd_state *wd, uae_u8 status, int delay)
 {
-       queue_index++;
-       if (queue_index >= WD_STATUS_QUEUE)
-               queue_index = 0;
-       scsidelay_status[queue_index] = status;
-       scsidelay_irq[queue_index] = delay == 0 ? 1 : (delay <= 2 ? 2 : delay);
+       wd->queue_index++;
+       if (wd->queue_index >= WD_STATUS_QUEUE)
+               wd->queue_index = 0;
+       wd->scsidelay_status[wd->queue_index] = status;
+       wd->scsidelay_irq[wd->queue_index] = delay == 0 ? 1 : (delay <= 2 ? 2 : delay);
 }
 
-static void set_status (uae_u8 status)
+static void set_status (struct wd_state *wd, uae_u8 status)
 {
-       set_status (status, 0);
+       set_status (wd, status, 0);
 }
 
-static uae_u32 gettc (void)
+static uae_u32 gettc (struct wd_state *wd)
 {
-       return wdregs[WD_TRANSFER_COUNT_LSB] | (wdregs[WD_TRANSFER_COUNT] << 8) | (wdregs[WD_TRANSFER_COUNT_MSB] << 16);
+       return wd->wdregs[WD_TRANSFER_COUNT_LSB] | (wd->wdregs[WD_TRANSFER_COUNT] << 8) | (wd->wdregs[WD_TRANSFER_COUNT_MSB] << 16);
 }
-static void settc (uae_u32 tc)
+static void settc (struct wd_state *wd, uae_u32 tc)
 {
-       wdregs[WD_TRANSFER_COUNT_LSB] = tc & 0xff;
-       wdregs[WD_TRANSFER_COUNT] = (tc >> 8) & 0xff;
-       wdregs[WD_TRANSFER_COUNT_MSB] = (tc >> 16) & 0xff;
+       wd->wdregs[WD_TRANSFER_COUNT_LSB] = tc & 0xff;
+       wd->wdregs[WD_TRANSFER_COUNT] = (tc >> 8) & 0xff;
+       wd->wdregs[WD_TRANSFER_COUNT_MSB] = (tc >> 16) & 0xff;
 }
-static bool decreasetc (void)
+static bool decreasetc (struct wd_state *wd)
 {
-       uae_u32 tc = gettc ();
+       uae_u32 tc = gettc (wd);
        if (!tc)
                return true;
        tc--;
-       settc (tc);
+       settc (wd, tc);
        return tc == 0;
 }
 
-static bool canwddma (void)
+static bool canwddma (struct wd_state *wd)
 {
-       uae_u8 mode = wdregs[WD_CONTROL] >> 5;
+       uae_u8 mode = wd->wdregs[WD_CONTROL] >> 5;
        if (mode != 0 && mode != 4 && mode != 1) {
                write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
        }
        return mode == 4 || mode == 1;
 }
 
-static TCHAR *scsitostring (void)
+static TCHAR *scsitostring (struct wd_state *wd)
 {
        static TCHAR buf[200];
        TCHAR *p;
@@ -358,74 +340,74 @@ static TCHAR *scsitostring (void)
 
        p = buf;
        p[0] = 0;
-       for (i = 0; i < scsi->offset && i < sizeof wd_data; i++) {
+       for (i = 0; i < wd->scsi->offset && i < sizeof wd->wd_data; i++) {
                if (i > 0) {
                        _tcscat (p, _T("."));
                        p++;
                }
-               _stprintf (p, _T("%02X"), wd_data[i]);
+               _stprintf (p, _T("%02X"), wd->wd_data[i]);
                p += _tcslen (p);
        }
        return buf;
 }
 
-static void dmacheck (void)
+static void dmacheck (struct wd_state *wd)
 {
-       dmac_acr++;
-       if (old_dmac && (dmac_cntr & CNTR_TCEN)) {
-               if (dmac_wtc == 0)
-                       dmac_istr |= ISTR_E_INT;
+       wd->dmac_acr++;
+       if (wd->old_dmac && (wd->dmac_cntr & CNTR_TCEN)) {
+               if (wd->dmac_wtc == 0)
+                       wd->dmac_istr |= ISTR_E_INT;
                else
-                       dmac_wtc--;
+                       wd->dmac_wtc--;
        }
 }
 
-static void setphase (uae_u8 phase)
+static void setphase (struct wd_state *wd, uae_u8 phase)
 {
-       wdregs[WD_COMMAND_PHASE] = phase;
+       wd->wdregs[WD_COMMAND_PHASE] = phase;
 }
 
-static bool do_dma (void)
+static bool do_dma (struct wd_state *wd)
 {
-       wd_data_avail = 0;
-       if (currprefs.cs_cdtvscsi)
-               cdtv_getdmadata (&dmac_acr);
-       if (scsi->direction == 0) {
+       wd->wd_data_avail = 0;
+       if (wd->cdtv)
+               cdtv_getdmadata (&wd->dmac_acr);
+       if (wd->scsi->direction == 0) {
                write_log (_T("%s DMA but no data!?\n"), WD33C93);
-       } else if (scsi->direction < 0) {
-               uaecptr odmac_acr = dmac_acr;
+       } else if (wd->scsi->direction < 0) {
+               uaecptr odmac_acr = wd->dmac_acr;
                for (;;) {
                        uae_u8 v;
-                       int status = scsi_receive_data (scsi, &v);
-                       put_byte (dmac_acr, v);
-                       if (wd_dataoffset < sizeof wd_data)
-                               wd_data[wd_dataoffset++] = v;
-                       dmacheck ();
-                       if (decreasetc ())
+                       int status = scsi_receive_data (wd->scsi, &v);
+                       put_byte (wd->dmac_acr, v);
+                       if (wd->wd_dataoffset < sizeof wd->wd_data)
+                               wd->wd_data[wd->wd_dataoffset++] = v;
+                       dmacheck (wd);
+                       if (decreasetc (wd))
                                break;
                        if (status)
                                break;
                }
 #if WD33C93_DEBUG > 0
-               write_log (_T("%s Done DMA from WD, %d/%d %08X\n"), WD33C93, scsi->offset, scsi->data_len, odmac_acr);
+               write_log (_T("%s Done DMA from WD, %d/%d %08X\n"), WD33C93, wd->scsi->offset, wd->scsi->data_len, odmac_acr);
 #endif
                return true;
-       } else if (scsi->direction > 0) {
-               uaecptr odmac_acr = dmac_acr;
+       } else if (wd->scsi->direction > 0) {
+               uaecptr odmac_acr = wd->dmac_acr;
                for (;;) {
                        int status;
-                       uae_u8 v = get_byte (dmac_acr);
-                       if (wd_dataoffset < sizeof wd_data)
-                               wd_data[wd_dataoffset++] = v;
-                       status = scsi_send_data (scsi, v);
-                       dmacheck ();
-                       if (decreasetc ())
+                       uae_u8 v = get_byte (wd->dmac_acr);
+                       if (wd->wd_dataoffset < sizeof wd->wd_data)
+                               wd->wd_data[wd->wd_dataoffset++] = v;
+                       status = scsi_send_data (wd->scsi, v);
+                       dmacheck (wd);
+                       if (decreasetc (wd))
                                break;
                        if (status)
                                break;
                }
 #if WD33C93_DEBUG > 0
-               write_log (_T("%s Done DMA to WD, %d/%d %08x\n"), WD33C93, scsi->offset, scsi->data_len, odmac_acr);
+               write_log (_T("%s Done DMA to WD, %d/%d %08x\n"), WD33C93, wd->scsi->offset, wd->scsi->data_len, odmac_acr);
 #endif
                return true;
        }
@@ -433,384 +415,384 @@ static bool do_dma (void)
 }
 
 
-static bool wd_do_transfer_out (void)
+static bool wd_do_transfer_out (struct wd_state *wd)
 {
 #if WD33C93_DEBUG > 0
-       write_log (_T("%s SCSI O [%02X] %d/%d TC=%d %s\n"), WD33C93, wdregs[WD_COMMAND_PHASE], scsi->offset, scsi->data_len, gettc (), scsitostring ());
+       write_log (_T("%s SCSI O [%02X] %d/%d TC=%d %s\n"), WD33C93, wd->wdregs[WD_COMMAND_PHASE], wd->scsi->offset, wd->scsi->data_len, gettc (wd), scsitostring (wd));
 #endif
-       if (wdregs[WD_COMMAND_PHASE] < 0x20) {
-               int msg = wd_data[0];
+       if (wd->wdregs[WD_COMMAND_PHASE] < 0x20) {
+               int msg = wd->wd_data[0];
                /* message was sent */
-               setphase (0x20);
-               wd_phase = CSR_XFER_DONE | PHS_COMMAND;
-               scsi->status = 0;
-               scsi_start_transfer (scsi);
+               setphase (wd, 0x20);
+               wd->wd_phase = CSR_XFER_DONE | PHS_COMMAND;
+               wd->scsi->status = 0;
+               scsi_start_transfer (wd->scsi);
 #if WD33C93_DEBUG > 0
                write_log (_T("%s SCSI got MESSAGE %02X\n"), WD33C93, msg);
 #endif
-               scsi->message[0] = msg;
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x30) {
+               wd->scsi->message[0] = msg;
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x30) {
 #if WD33C93_DEBUG > 0
-               write_log (_T("%s SCSI got COMMAND %02X\n"), WD33C93, wd_data[0]);
+               write_log (_T("%s SCSI got COMMAND %02X\n"), WD33C93, wd->wd_data[0]);
 #endif
-               if (scsi->offset < scsi->data_len) {
+               if (wd->scsi->offset < wd->scsi->data_len) {
                        // data missing, ask for more
-                       wd_phase = CSR_XFER_DONE | PHS_COMMAND;
-                       setphase (0x30 + scsi->offset);
-                       set_status (wd_phase, 1);
+                       wd->wd_phase = CSR_XFER_DONE | PHS_COMMAND;
+                       setphase (wd, 0x30 + wd->scsi->offset);
+                       set_status (wd, wd->wd_phase, 1);
                        return false;
                }
-               settc (0);
-               scsi_start_transfer (scsi);
-               scsi_emulate_analyze (scsi);
-               if (scsi->direction > 0) {
+               settc (wd, 0);
+               scsi_start_transfer (wd->scsi);
+               scsi_emulate_analyze (wd->scsi);
+               if (wd->scsi->direction > 0) {
                        /* if write command, need to wait for data */
-                       if (scsi->data_len <= 0 || scsi->direction == 0) {
+                       if (wd->scsi->data_len <= 0 || wd->scsi->direction == 0) {
                                // Status phase if command didn't return anything and don't want anything
-                               wd_phase = CSR_XFER_DONE | PHS_STATUS;
-                               setphase (0x46);
+                               wd->wd_phase = CSR_XFER_DONE | PHS_STATUS;
+                               setphase (wd, 0x46);
                        } else {
-                               wd_phase = CSR_XFER_DONE | PHS_DATA_OUT;
-                               setphase (0x45);
+                               wd->wd_phase = CSR_XFER_DONE | PHS_DATA_OUT;
+                               setphase (wd, 0x45);
                        }
                } else {
-                       scsi_emulate_cmd (scsi);
-                       if (scsi->data_len <= 0 || scsi->direction == 0) {
+                       scsi_emulate_cmd (wd->scsi);
+                       if (wd->scsi->data_len <= 0 || wd->scsi->direction == 0) {
                                // Status phase if command didn't return anything and don't want anything
-                               wd_phase = CSR_XFER_DONE | PHS_STATUS;
-                               setphase (0x46);
+                               wd->wd_phase = CSR_XFER_DONE | PHS_STATUS;
+                               setphase (wd, 0x46);
                        } else {
-                               wd_phase = CSR_XFER_DONE | PHS_DATA_IN;
-                               setphase (0x45); // just skip all reselection and message stuff for now..
+                               wd->wd_phase = CSR_XFER_DONE | PHS_DATA_IN;
+                               setphase (wd, 0x45); // just skip all reselection and message stuff for now..
                        }
                }
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x46 || wdregs[WD_COMMAND_PHASE] == 0x45) {
-               if (scsi->offset < scsi->data_len) {
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x46 || wd->wdregs[WD_COMMAND_PHASE] == 0x45) {
+               if (wd->scsi->offset < wd->scsi->data_len) {
                        // data missing, ask for more
-                       wd_phase = CSR_XFER_DONE | (scsi->direction < 0 ? PHS_DATA_IN : PHS_DATA_OUT);
-                       set_status (wd_phase, 10);
+                       wd->wd_phase = CSR_XFER_DONE | (wd->scsi->direction < 0 ? PHS_DATA_IN : PHS_DATA_OUT);
+                       set_status (wd, wd->wd_phase, 10);
                        return false;
                }
-               settc (0);
-               if (scsi->direction > 0) {
+               settc (wd, 0);
+               if (wd->scsi->direction > 0) {
                        /* data was sent */
-                       scsi_emulate_cmd (scsi);
-                       scsi->data_len = 0;
-                       wd_phase = CSR_XFER_DONE | PHS_STATUS;
+                       scsi_emulate_cmd (wd->scsi);
+                       wd->scsi->data_len = 0;
+                       wd->wd_phase = CSR_XFER_DONE | PHS_STATUS;
                }
-               scsi_start_transfer (scsi);
-               setphase (0x47);
+               scsi_start_transfer (wd->scsi);
+               setphase (wd, 0x47);
        }
-       wd_dataoffset = 0;
-       set_status (wd_phase, scsi->direction <= 0 ? 0 : 1);
-       wd_busy = 0;
+       wd->wd_dataoffset = 0;
+       set_status (wd, wd->wd_phase, wd->scsi->direction <= 0 ? 0 : 1);
+       wd->wd_busy = 0;
        return true;
 }
 
-static bool wd_do_transfer_in (void)
+static bool wd_do_transfer_in (struct wd_state *wd)
 {
 #if WD33C93_DEBUG > 0
-       write_log (_T("%s SCSI I [%02X] %d/%d TC=%d %s\n"), WD33C93, wdregs[WD_COMMAND_PHASE], scsi->offset, scsi->data_len, gettc (), scsitostring ());
+       write_log (_T("%s SCSI I [%02X] %d/%d TC=%d %s\n"), WD33C93, wd->wdregs[WD_COMMAND_PHASE], wd->scsi->offset, wd->scsi->data_len, gettc (wd), scsitostring (wd));
 #endif
-       wd_dataoffset = 0;
-       if (wdregs[WD_COMMAND_PHASE] >= 0x36 && wdregs[WD_COMMAND_PHASE] < 0x46) {
-               if (scsi->offset < scsi->data_len) {
+       wd->wd_dataoffset = 0;
+       if (wd->wdregs[WD_COMMAND_PHASE] >= 0x36 && wd->wdregs[WD_COMMAND_PHASE] < 0x46) {
+               if (wd->scsi->offset < wd->scsi->data_len) {
                        // data missing, ask for more
-                       wd_phase = CSR_XFER_DONE | (scsi->direction < 0 ? PHS_DATA_IN : PHS_DATA_OUT);
-                       set_status (wd_phase, 1);
+                       wd->wd_phase = CSR_XFER_DONE | (wd->scsi->direction < 0 ? PHS_DATA_IN : PHS_DATA_OUT);
+                       set_status (wd, wd->wd_phase, 1);
                        return false;
                }
-               if (gettc () != 0) {
-                       wd_phase = CSR_UNEXP | PHS_STATUS;
-                       setphase (0x46);
+               if (gettc (wd) != 0) {
+                       wd->wd_phase = CSR_UNEXP | PHS_STATUS;
+                       setphase (wd, 0x46);
                } else {
-                       wd_phase = CSR_XFER_DONE | PHS_STATUS;
-                       setphase (0x46);
+                       wd->wd_phase = CSR_XFER_DONE | PHS_STATUS;
+                       setphase (wd, 0x46);
                }
-               scsi_start_transfer (scsi);
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x46 || wdregs[WD_COMMAND_PHASE] == 0x47) {
-               setphase (0x50);
-               wd_phase = CSR_XFER_DONE | PHS_MESS_IN;
-               scsi_start_transfer (scsi);
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x50) {
-               setphase (0x60);
-               wd_phase = CSR_DISC;
-               wd_selected = false;
-               scsi_start_transfer (scsi);
+               scsi_start_transfer (wd->scsi);
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x46 || wd->wdregs[WD_COMMAND_PHASE] == 0x47) {
+               setphase (wd, 0x50);
+               wd->wd_phase = CSR_XFER_DONE | PHS_MESS_IN;
+               scsi_start_transfer (wd->scsi);
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x50) {
+               setphase (wd, 0x60);
+               wd->wd_phase = CSR_DISC;
+               wd->wd_selected = false;
+               scsi_start_transfer (wd->scsi);
        }
-       set_status (wd_phase, 1);
-       scsi->direction = 0;
+       set_status (wd, wd->wd_phase, 1);
+       wd->scsi->direction = 0;
        return true;
 }
 
-static void wd_cmd_sel_xfer (bool atn)
+static void wd_cmd_sel_xfer (struct wd_state *wd, bool atn)
 {
        int i, tmp_tc;
        int delay = 0;
 
-       wd_data_avail = 0;
-       tmp_tc = gettc ();
-       scsi = scsis[wdregs[WD_DESTINATION_ID] & 7];
-       if (!scsi) {
-               set_status (CSR_TIMEOUT, 0);
-               wdregs[WD_COMMAND_PHASE] = 0x00;
+       wd->wd_data_avail = 0;
+       tmp_tc = gettc (wd);
+       wd->scsi = wd->scsis[wd->wdregs[WD_DESTINATION_ID] & 7];
+       if (!wd->scsi) {
+               set_status (wd, CSR_TIMEOUT, 0);
+               wd->wdregs[WD_COMMAND_PHASE] = 0x00;
 #if WD33C93_DEBUG > 0
                write_log (_T("* %s select and transfer%s, ID=%d: No device\n"),
-               WD33C93, atn ? _T(" with atn") : _T(""), wdregs[WD_DESTINATION_ID] & 0x7);
+                       WD33C93, atn ? _T(" with atn") : _T(""), wd->wdregs[WD_DESTINATION_ID] & 0x7);
 #endif
                return;
        }
-       if (!wd_selected) {
-               scsi->message[0] = 0x80;
-               wd_selected = true;
-               wdregs[WD_COMMAND_PHASE] = 0x10;
+       if (!wd->wd_selected) {
+               wd->scsi->message[0] = 0x80;
+               wd->wd_selected = true;
+               wd->wdregs[WD_COMMAND_PHASE] = 0x10;
        }
 #if WD33C93_DEBUG > 0
        write_log (_T("* %s select and transfer%s, ID=%d PHASE=%02X TC=%d wddma=%d dmac=%d\n"),
-               WD33C93, atn ? _T(" with atn") : _T(""), wdregs[WD_DESTINATION_ID] & 0x7, wdregs[WD_COMMAND_PHASE], tmp_tc, wdregs[WD_CONTROL] >> 5, dmac_dma);
+               WD33C93, atn ? _T(" with atn") : _T(""), wd->wdregs[WD_DESTINATION_ID] & 0x7, wd->wdregs[WD_COMMAND_PHASE], tmp_tc, wd->wdregs[WD_CONTROL] >> 5, wd->dmac_dma);
 #endif
-       if (wdregs[WD_COMMAND_PHASE] <= 0x30) {
-               scsi->buffer[0] = 0;
-               scsi->status = 0;
-               memcpy (scsi->cmd, &wdregs[3], 16);
-               scsi->data_len = tmp_tc;
-               scsi_emulate_analyze (scsi);
-               settc (scsi->cmd_len);
-               wd_dataoffset = 0;
-               scsi_start_transfer (scsi);
-               scsi->direction = 2;
-               scsi->data_len = scsi->cmd_len;
-               for (i = 0; i < gettc (); i++) {
-                       uae_u8 b = scsi->cmd[i];
-                       wd_data[i] = b;
-                       scsi_send_data (scsi, b);
-                       wd_dataoffset++;
+       if (wd->wdregs[WD_COMMAND_PHASE] <= 0x30) {
+               wd->scsi->buffer[0] = 0;
+               wd->scsi->status = 0;
+               memcpy (wd->scsi->cmd, &wd->wdregs[3], 16);
+               wd->scsi->data_len = tmp_tc;
+               scsi_emulate_analyze (wd->scsi);
+               settc (wd, wd->scsi->cmd_len);
+               wd->wd_dataoffset = 0;
+               scsi_start_transfer (wd->scsi);
+               wd->scsi->direction = 2;
+               wd->scsi->data_len = wd->scsi->cmd_len;
+               for (i = 0; i < gettc (wd); i++) {
+                       uae_u8 b = wd->scsi->cmd[i];
+                       wd->wd_data[i] = b;
+                       scsi_send_data (wd->scsi, b);
+                       wd->wd_dataoffset++;
                }
                // 0x30 = command phase has started
-               scsi->data_len = tmp_tc;
-               scsi_emulate_analyze (scsi);
-               wdregs[WD_COMMAND_PHASE] = 0x30 + gettc ();
-               settc (0);
+               wd->scsi->data_len = tmp_tc;
+               scsi_emulate_analyze (wd->scsi);
+               wd->wdregs[WD_COMMAND_PHASE] = 0x30 + gettc (wd);
+               settc (wd, 0);
 #if WD33C93_DEBUG > 0
-               write_log (_T("%s: Got Command %s, datalen=%d\n"), WD33C93, scsitostring (), scsi->data_len);
+               write_log (_T("%s: Got Command %s, datalen=%d\n"), WD33C93, scsitostring (wd), wd->scsi->data_len);
 #endif
        }
 
-       if (wdregs[WD_COMMAND_PHASE] <= 0x41) {
-               wdregs[WD_COMMAND_PHASE] = 0x44;
+       if (wd->wdregs[WD_COMMAND_PHASE] <= 0x41) {
+               wd->wdregs[WD_COMMAND_PHASE] = 0x44;
 #if 0
-               if (wdregs[WD_CONTROL] & CTL_IDI) {
-                       wd_phase = CSR_DISC;
-                       set_status (wd_phase, delay);
-                       wd_phase = CSR_RESEL;
-                       set_status (wd_phase, delay + 10);
+               if (wd->wdregs[WD_CONTROL] & CTL_IDI) {
+                       wd->wd_phase = CSR_DISC;
+                       set_status (wd, wd->wd_phase, delay);
+                       wd->wd_phase = CSR_RESEL;
+                       set_status (wd, wd->wd_phase, delay + 10);
                        return;
                }
 #endif
-               wdregs[WD_COMMAND_PHASE] = 0x44;
+               wd->wdregs[WD_COMMAND_PHASE] = 0x44;
        }
 
        // target replied or start/continue data phase (if data available)
-       if (wdregs[WD_COMMAND_PHASE] == 0x44) {
-               if (scsi->direction <= 0) {
-                       scsi_emulate_cmd (scsi);
+       if (wd->wdregs[WD_COMMAND_PHASE] == 0x44) {
+               if (wd->scsi->direction <= 0) {
+                       scsi_emulate_cmd (wd->scsi);
                }
-               scsi_start_transfer (scsi);
-               wdregs[WD_COMMAND_PHASE] = 0x45;
+               scsi_start_transfer (wd->scsi);
+               wd->wdregs[WD_COMMAND_PHASE] = 0x45;
        }
                
-       if (wdregs[WD_COMMAND_PHASE] == 0x45) {
-               settc (tmp_tc);
-               wd_dataoffset = 0;
-               setphase (0x45);
+       if (wd->wdregs[WD_COMMAND_PHASE] == 0x45) {
+               settc (wd, tmp_tc);
+               wd->wd_dataoffset = 0;
+               setphase (wd, 0x45);
 
-               if (gettc () == 0) {
-                       if (scsi->direction != 0) {
+               if (gettc (wd) == 0) {
+                       if (wd->scsi->direction != 0) {
                                // TC = 0 but we may have data
-                               if (scsi->direction < 0) {
-                                       if (scsi->data_len == 0) {
+                               if (wd->scsi->direction < 0) {
+                                       if (wd->scsi->data_len == 0) {
                                                // no data, continue normally to status phase
-                                               setphase (0x46);
+                                               setphase (wd, 0x46);
                                                goto end;
                                        }
                                }
-                               wd_phase = CSR_UNEXP;
-                               if (scsi->direction < 0)
-                                       wd_phase |= PHS_DATA_IN;
+                               wd->wd_phase = CSR_UNEXP;
+                               if (wd->scsi->direction < 0)
+                                       wd->wd_phase |= PHS_DATA_IN;
                                else
-                                       wd_phase |= PHS_DATA_OUT;
-                               set_status (wd_phase, 1);
+                                       wd->wd_phase |= PHS_DATA_OUT;
+                               set_status (wd, wd->wd_phase, 1);
                                return;
                        }
                }
 
-               if (scsi->direction) {
-                       if (canwddma ()) {
-                               if (scsi->direction <= 0) {
-                                       do_dma ();
-                                       if (scsi->offset < scsi->data_len) {
+               if (wd->scsi->direction) {
+                       if (canwddma (wd)) {
+                               if (wd->scsi->direction <= 0) {
+                                       do_dma (wd);
+                                       if (wd->scsi->offset < wd->scsi->data_len) {
                                                // buffer not completely retrieved?
-                                               wd_phase = CSR_UNEXP | PHS_DATA_IN;
-                                               set_status (wd_phase, 1);
+                                               wd->wd_phase = CSR_UNEXP | PHS_DATA_IN;
+                                               set_status (wd, wd->wd_phase, 1);
                                                return;
                                        }
-                                       if (gettc () > 0) {
+                                       if (gettc (wd) > 0) {
                                                // requested more data than was available.
-                                               wd_phase = CSR_UNEXP | PHS_STATUS;
-                                               set_status (wd_phase, 1);
+                                               wd->wd_phase = CSR_UNEXP | PHS_STATUS;
+                                               set_status (wd, wd->wd_phase, 1);
                                                return;
                                        }
-                                       setphase (0x46);
+                                       setphase (wd, 0x46);
                                } else {
-                                       if (do_dma ()) {
-                                               setphase (0x46);
-                                               if (scsi->offset < scsi->data_len) {
+                                       if (do_dma (wd)) {
+                                               setphase (wd, 0x46);
+                                               if (wd->scsi->offset < wd->scsi->data_len) {
                                                        // not enough data?
-                                                       wd_phase = CSR_UNEXP | PHS_DATA_OUT;
-                                                       set_status (wd_phase, 1);
+                                                       wd->wd_phase = CSR_UNEXP | PHS_DATA_OUT;
+                                                       set_status (wd, wd->wd_phase, 1);
                                                        return;
                                                }
                                                // got all data -> execute it
-                                               scsi_emulate_cmd (scsi);
+                                               scsi_emulate_cmd (wd->scsi);
                                        }
                                }
                        } else {
                                // no dma = Service Request
-                               wd_phase = CSR_SRV_REQ;
-                               if (scsi->direction < 0)
-                                       wd_phase |= PHS_DATA_IN;
+                               wd->wd_phase = CSR_SRV_REQ;
+                               if (wd->scsi->direction < 0)
+                                       wd->wd_phase |= PHS_DATA_IN;
                                else
-                                       wd_phase |= PHS_DATA_OUT;
-                               set_status (wd_phase, 1);
+                                       wd->wd_phase |= PHS_DATA_OUT;
+                               set_status (wd, wd->wd_phase, 1);
                                return;
                        }
                } else {
                        // TC > 0 but no data to transfer
-                       if (gettc ()) {
-                               wd_phase = CSR_UNEXP | PHS_STATUS;
-                               set_status (wd_phase, 1);
+                       if (gettc (wd)) {
+                               wd->wd_phase = CSR_UNEXP | PHS_STATUS;
+                               set_status (wd, wd->wd_phase, 1);
                                return;
                        }
-                       wdregs[WD_COMMAND_PHASE] = 0x46;
+                       wd->wdregs[WD_COMMAND_PHASE] = 0x46;
                }
        }
 
        end:
-       if (wdregs[WD_COMMAND_PHASE] == 0x46) {
-               scsi->buffer[0] = 0;
-               wdregs[WD_COMMAND_PHASE] = 0x50;
-               wdregs[WD_TARGET_LUN] = scsi->status;
-               scsi->buffer[0] = scsi->status;
+       if (wd->wdregs[WD_COMMAND_PHASE] == 0x46) {
+               wd->scsi->buffer[0] = 0;
+               wd->wdregs[WD_COMMAND_PHASE] = 0x50;
+               wd->wdregs[WD_TARGET_LUN] = wd->scsi->status;
+               wd->scsi->buffer[0] = wd->scsi->status;
        }
 
        // 0x60 = command complete
-       wdregs[WD_COMMAND_PHASE] = 0x60;
-       if (!(wdregs[WD_CONTROL] & CTL_EDI)) {
-               wd_phase = CSR_SEL_XFER_DONE;
+       wd->wdregs[WD_COMMAND_PHASE] = 0x60;
+       if (!(wd->wdregs[WD_CONTROL] & CTL_EDI)) {
+               wd->wd_phase = CSR_SEL_XFER_DONE;
                delay += 2;
-               set_status (wd_phase, delay);
+               set_status (wd, wd->wd_phase, delay);
                delay += 2;
-               wd_phase = CSR_DISC;
-               set_status (wd_phase, delay);
+               wd->wd_phase = CSR_DISC;
+               set_status (wd, wd->wd_phase, delay);
        } else {
                delay += 2;
-               wd_phase = CSR_SEL_XFER_DONE;
-               set_status (wd_phase, delay);
+               wd->wd_phase = CSR_SEL_XFER_DONE;
+               set_status (wd, wd->wd_phase, delay);
        }
-       wd_selected = 0;
+       wd->wd_selected = 0;
 }
 
 
-static void wd_cmd_trans_info (void)
+static void wd_cmd_trans_info (struct wd_state *wd)
 {
-       if (wdregs[WD_COMMAND_PHASE] == 0x20) {
-               wdregs[WD_COMMAND_PHASE] = 0x30;
-               scsi->status = 0;
+       if (wd->wdregs[WD_COMMAND_PHASE] == 0x20) {
+               wd->wdregs[WD_COMMAND_PHASE] = 0x30;
+               wd->scsi->status = 0;
        }
-       wd_busy = 1;
-       if (wdregs[WD_COMMAND] & 0x80)
-               settc (1);
-       if (gettc () == 0)
-               settc (1);
-       wd_dataoffset = 0;
-
-
-//     if (wdregs[WD_COMMAND_PHASE] >= 0x36 && wdregs[WD_COMMAND_PHASE] <= 0x3f) {
-//             wdregs[WD_COMMAND_PHASE] = 0x45;
-//     } else if (wdregs[WD_COMMAND_PHASE] == 0x41) {
-//             wdregs[WD_COMMAND_PHASE] = 0x46;
+       wd->wd_busy = 1;
+       if (wd->wdregs[WD_COMMAND] & 0x80)
+               settc (wd, 1);
+       if (gettc (wd) == 0)
+               settc (wd, 1);
+       wd->wd_dataoffset = 0;
+
+
+//     if (wd->wdregs[WD_COMMAND_PHASE] >= 0x36 && wd->wdregs[WD_COMMAND_PHASE] <= 0x3f) {
+//             wd->wdregs[WD_COMMAND_PHASE] = 0x45;
+//     } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x41) {
+//             wd->wdregs[WD_COMMAND_PHASE] = 0x46;
 //     }
 
 #if 0
-       if (wdregs[WD_COMMAND_PHASE] >= 0x40 && scsi->direction < 0) {
-               if (wd_tc > scsi->data_len) {
-                       wd_tc = scsi->data_len;
-                       if (wd_tc < 0)
-                               wd_tc = 0;
+       if (wd->wdregs[WD_COMMAND_PHASE] >= 0x40 && wd->scsi->direction < 0) {
+               if (wd->wd_tc > wd->scsi->data_len) {
+                       wd->wd_tc = wd->scsi->data_len;
+                       if (wd->wd_tc < 0)
+                               wd->wd_tc = 0;
                }
        }
 #endif
-       if (wdregs[WD_COMMAND_PHASE] == 0x30) {
-               scsi->direction = 2; // command
-               scsi->cmd_len = scsi->data_len = gettc ();
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x10) {
-               scsi->direction = 1; // message
-               scsi->data_len = gettc ();
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x45) {
-               scsi_emulate_analyze (scsi);
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x46 || wdregs[WD_COMMAND_PHASE] == 0x47) {
-               scsi->buffer[0] = scsi->status;
-               wdregs[WD_TARGET_LUN] = scsi->status;
-               scsi->direction = -1; // status
-               scsi->data_len = 1;
-       } else if (wdregs[WD_COMMAND_PHASE] == 0x50) {
-               scsi->direction = -1;
-               scsi->data_len = gettc ();
+       if (wd->wdregs[WD_COMMAND_PHASE] == 0x30) {
+               wd->scsi->direction = 2; // command
+               wd->scsi->cmd_len = wd->scsi->data_len = gettc (wd);
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x10) {
+               wd->scsi->direction = 1; // message
+               wd->scsi->data_len = gettc (wd);
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x45) {
+               scsi_emulate_analyze (wd->scsi);
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x46 || wd->wdregs[WD_COMMAND_PHASE] == 0x47) {
+               wd->scsi->buffer[0] = wd->scsi->status;
+               wd->wdregs[WD_TARGET_LUN] = wd->scsi->status;
+               wd->scsi->direction = -1; // status
+               wd->scsi->data_len = 1;
+       } else if (wd->wdregs[WD_COMMAND_PHASE] == 0x50) {
+               wd->scsi->direction = -1;
+               wd->scsi->data_len = gettc (wd);
        }
 
-       if (canwddma ()) {
-               wd_data_avail = -1;
+       if (canwddma (wd)) {
+               wd->wd_data_avail = -1;
        } else {
-               wd_data_avail = 1;
+               wd->wd_data_avail = 1;
        }
 
 #if WD33C93_DEBUG > 0
        write_log (_T("* %s transfer info phase=%02x TC=%d dir=%d data=%d/%d wddma=%d dmac=%d\n"),
-               WD33C93, wdregs[WD_COMMAND_PHASE], gettc (), scsi->direction, scsi->offset, scsi->data_len, wdregs[WD_CONTROL] >> 5, dmac_dma);
+               WD33C93, wd->wdregs[WD_COMMAND_PHASE], gettc (wd), wd->scsi->direction, wd->scsi->offset, wd->scsi->data_len, wd->wdregs[WD_CONTROL] >> 5, wd->dmac_dma);
 #endif
 
 }
 
-static void wd_cmd_sel (bool atn)
+static void wd_cmd_sel (struct wd_state *wd, bool atn)
 {
 #if WD33C93_DEBUG > 0
-       write_log (_T("* %s select%s, ID=%d\n"), WD33C93, atn ? _T(" with atn") : _T(""), wdregs[WD_DESTINATION_ID] & 0x7);
+       write_log (_T("* %s select%s, ID=%d\n"), WD33C93, atn ? _T(" with atn") : _T(""), wd->wdregs[WD_DESTINATION_ID] & 0x7);
 #endif
-       wd_phase = 0;
-       wdregs[WD_COMMAND_PHASE] = 0;
+       wd->wd_phase = 0;
+       wd->wdregs[WD_COMMAND_PHASE] = 0;
 
-       scsi = scsis[wdregs[WD_DESTINATION_ID] & 7];
-       if (!scsi) {
+       wd->scsi = wd->scsis[wd->wdregs[WD_DESTINATION_ID] & 7];
+       if (!wd->scsi) {
 #if WD33C93_DEBUG > 0
                write_log (_T("%s no drive\n"), WD33C93);
 #endif
-               set_status (CSR_TIMEOUT, 1000);
+               set_status (wd, CSR_TIMEOUT, 1000);
                return;
        }
-       scsi_start_transfer (scsi);
-       wd_selected = true;
-       scsi->message[0] = 0x80;
-       set_status (CSR_SELECT, 2);
+       scsi_start_transfer (wd->scsi);
+       wd->wd_selected = true;
+       wd->scsi->message[0] = 0x80;
+       set_status (wd, CSR_SELECT, 2);
        if (atn) {
-               wdregs[WD_COMMAND_PHASE] = 0x10;
-               set_status (CSR_SRV_REQ | PHS_MESS_OUT, 4);
+               wd->wdregs[WD_COMMAND_PHASE] = 0x10;
+               set_status (wd, CSR_SRV_REQ | PHS_MESS_OUT, 4);
        } else {
-               wdregs[WD_COMMAND_PHASE] = 0x10; // connected as an initiator
-               set_status (CSR_SRV_REQ | PHS_COMMAND, 4);
+               wd->wdregs[WD_COMMAND_PHASE] = 0x10; // connected as an initiator
+               set_status (wd, CSR_SRV_REQ | PHS_COMMAND, 4);
        } 
 }
 
-static void wd_cmd_reset (bool irq)
+static void wd_cmd_reset (struct wd_state *wd, bool irq)
 {
        int i;
 
@@ -819,63 +801,73 @@ static void wd_cmd_reset (bool irq)
                write_log (_T("%s reset\n"), WD33C93);
 #endif
        for (i = 1; i < 0x16; i++)
-               wdregs[i] = 0;
-       wdregs[0x18] = 0;
-       sasr = 0;
-       wd_selected = false;
-       scsi = NULL;
-       scsidelay_irq[0] = 0;
-       scsidelay_irq[1] = 0;
-       auxstatus = 0;
-       wd_data_avail = 0;
+               wd->wdregs[i] = 0;
+       wd->wdregs[0x18] = 0;
+       wd->sasr = 0;
+       wd->wd_selected = false;
+       wd->scsi = NULL;
+       wd->scsidelay_irq[0] = 0;
+       wd->scsidelay_irq[1] = 0;
+       wd->auxstatus = 0;
+       wd->wd_data_avail = 0;
        if (irq) {
-               set_status ((wdregs[0] & 0x08) ? 1 : 0, 50);
+               set_status (wd, (wd->wdregs[0] & 0x08) ? 1 : 0, 50);
        } else {
-               dmac_dma = 0;
-               dmac_istr = 0;
-               dmac_cntr = 0;
+               wd->dmac_dma = 0;
+               wd->dmac_istr = 0;
+               wd->dmac_cntr = 0;
        }
 }
 
-static void wd_cmd_abort (void)
+static void wd_cmd_abort (struct wd_state *wd)
 {
 #if WD33C93_DEBUG > 0
        write_log (_T("%s abort\n"), WD33C93);
 #endif
 }
 
-void scsi_hsync (void)
+static void scsi_hsync2 (struct wd_state *wd)
 {
-       if (wd_data_avail < 0 && dmac_dma > 0) {
+       if (!wd->enabled)
+               return;
+       if (wd->wd_data_avail < 0 && wd->dmac_dma > 0) {
                bool v;
-               do_dma ();
-               if (scsi->direction < 0) {
-                       v = wd_do_transfer_in ();
-               } else if (scsi->direction > 0) {
-                       v = wd_do_transfer_out ();
+               do_dma (wd);
+               if (wd->scsi->direction < 0) {
+                       v = wd_do_transfer_in (wd);
+               } else if (wd->scsi->direction > 0) {
+                       v = wd_do_transfer_out (wd);
                } else {
                        write_log (_T("%s data transfer attempt without data!\n"), WD33C93);
                        v = true;
                }
                if (v) {
-                       scsi->direction = 0;
-                       wd_data_avail = 0;
+                       wd->scsi->direction = 0;
+                       wd->wd_data_avail = 0;
                } else {
-                       dmac_dma = -1;
+                       wd->dmac_dma = -1;
                }
        }
-       if (auxstatus & ASR_INT)
+       if (wd->auxstatus & ASR_INT)
                return;
        for (int i = 0; i < WD_STATUS_QUEUE; i++) {
-               if (scsidelay_irq[i] == 1) {
-                       scsidelay_irq[i] = 0;
-                       doscsistatus(scsidelay_status[i]);
-                       wd_busy = 0;
-               } else if (scsidelay_irq[i] > 1) {
-                       scsidelay_irq[i]--;
+               if (wd->scsidelay_irq[i] == 1) {
+                       wd->scsidelay_irq[i] = 0;
+                       doscsistatus(wd, wd->scsidelay_status[i]);
+                       wd->wd_busy = 0;
+               } else if (wd->scsidelay_irq[i] > 1) {
+                       wd->scsidelay_irq[i]--;
                }
        }
 }
+void scsi_hsync (void)
+{
+       scsi_hsync2(&wd_a2091);
+       scsi_hsync2(&wd_a2091_2);
+       scsi_hsync2(&wd_a3000);
+       scsi_hsync2(&wd_cdtv);
+}
+
 
 static int writeonlyreg (int reg)
 {
@@ -894,121 +886,122 @@ static uae_u32 makecmd (struct scsi_data *s, int msg, uae_u8 cmd)
        return v;
 }
 
-static void writewdreg (int sasr, uae_u8 val)
+static void writewdreg (struct wd_state *wd, int sasr, uae_u8 val)
 {
        switch (sasr)
        {
        case WD_OWN_ID:
-               if (wd33c93_ver == 0)
+               if (wd->wd33c93_ver == 0)
                        val &= ~(0x20 | 0x08);
-               else if (wd33c93_ver == 1)
+               else if (wd->wd33c93_ver == 1)
                        val &= ~0x20;
                break;
        }
        if (sasr > WD_QUEUE_TAG && sasr < WD_AUXILIARY_STATUS)
                return;
        // queue tag is B revision only
-       if (sasr == WD_QUEUE_TAG && wd33c93_ver < 2)
+       if (sasr == WD_QUEUE_TAG && wd->wd33c93_ver < 2)
                return;
-       wdregs[sasr] = val;
+       wd->wdregs[sasr] = val;
 }
 
-void wdscsi_put (uae_u8 d)
+void wdscsi_put (struct wd_state *wd, uae_u8 d)
 {
 #if WD33C93_DEBUG > 1
        if (WD33C93_DEBUG > 3 || sasr != WD_DATA)
                write_log (_T("W %s REG %02X = %02X (%d) PC=%08X\n"), WD33C93, sasr, d, d, M68K_GETPC);
 #endif
-       if (!writeonlyreg (sasr)) {
-               writewdreg (sasr, d);
+       if (!writeonlyreg (wd->sasr)) {
+               writewdreg (wd, wd->sasr, d);
        }
-       if (!wd_used) {
-               wd_used = 1;
-               write_log (_T("%s in use\n"), WD33C93);
+       if (!wd->wd_used) {
+               wd->wd_used = 1;
+               write_log (_T("%s %s in use\n"), wd->name, WD33C93);
        }
-       if (sasr == WD_COMMAND_PHASE) {
+       if (wd->sasr == WD_COMMAND_PHASE) {
 #if WD33C93_DEBUG > 1
                write_log (_T("%s PHASE=%02X\n"), WD33C93, d);
 #endif
                ;
-       } else if (sasr == WD_DATA) {
+       } else if (wd->sasr == WD_DATA) {
 #if WD33C93_DEBUG_PIO
-               write_log (_T("%s WD_DATA WRITE %02x %d/%d\n"), WD33C93, d, scsi->offset, scsi->data_len);
+               write_log (_T("%s WD_DATA WRITE %02x %d/%d\n"), WD33C93, d, wd->scsi->offset, wd->scsi->data_len);
 #endif
-               if (!wd_data_avail) {
+               if (!wd->wd_data_avail) {
                        write_log (_T("%s WD_DATA WRITE without data request!?\n"), WD33C93);
                        return;
                }
-               if (wd_dataoffset < sizeof wd_data)
-                       wd_data[wd_dataoffset] = wdregs[sasr];
-               wd_dataoffset++;
-               decreasetc ();
-               wd_data_avail = 1;
-               if (scsi_send_data (scsi, wdregs[sasr]) || gettc () == 0) {
-                       wd_data_avail = 0;
-                       write_comm_pipe_u32 (&requests, makecmd (scsi, 2, 0), 1);
+               if (wd->wd_dataoffset < sizeof wd->wd_data)
+                       wd->wd_data[wd->wd_dataoffset] = wd->wdregs[wd->sasr];
+               wd->wd_dataoffset++;
+               decreasetc (wd);
+               wd->wd_data_avail = 1;
+               if (scsi_send_data (wd->scsi, wd->wdregs[wd->sasr]) || gettc (wd) == 0) {
+                       wd->wd_data_avail = 0;
+                       write_comm_pipe_u32 (&wd->requests, makecmd (wd->scsi, 2, 0), 1);
                }
-       } else if (sasr == WD_COMMAND) {
-               wd_busy = true;
-               write_comm_pipe_u32 (&requests, makecmd (scsi, 0, d), 1);
-               if (scsi && scsi->cd_emu_unit >= 0)
-                       gui_flicker_led (LED_CD, scsi->id, 1);
+       } else if (wd->sasr == WD_COMMAND) {
+               wd->wd_busy = true;
+               write_comm_pipe_u32 (&wd->requests, makecmd (wd->scsi, 0, d), 1);
+               if (wd->scsi && wd->scsi->cd_emu_unit >= 0)
+                       gui_flicker_led (LED_CD, wd->scsi->id, 1);
        }
-       incsasr (1);
+       incsasr (wd, 1);
 }
 
-void wdscsi_sasr (uae_u8 b)
+void wdscsi_sasr (struct wd_state *wd, uae_u8 b)
 {
-       sasr = b;
+       wd->sasr = b;
 }
-uae_u8 wdscsi_getauxstatus (void)
+uae_u8 wdscsi_getauxstatus (struct wd_state *wd)
 {
-       return (auxstatus & ASR_INT) | (wd_busy || wd_data_avail < 0 ? ASR_BSY : 0) | (wd_data_avail != 0 ? ASR_DBR : 0);
+       return (wd->auxstatus & ASR_INT) | (wd->wd_busy || wd->wd_data_avail < 0 ? ASR_BSY : 0) | (wd->wd_data_avail != 0 ? ASR_DBR : 0);
 }
 
-uae_u8 wdscsi_get (void)
+uae_u8 wdscsi_get (struct wd_state *wd)
 {
        uae_u8 v;
 #if WD33C93_DEBUG > 1
-       uae_u8 osasr = sasr;
+       uae_u8 osasr = wd->sasr;
 #endif
 
-       v = wdregs[sasr];
-       if (sasr == WD_DATA) {
-               if (!wd_data_avail) {
+       v = wd->wdregs[wd->sasr];
+       if (wd->sasr == WD_DATA) {
+               if (!wd->wd_data_avail) {
                        write_log (_T("%s WD_DATA READ without data request!?\n"), WD33C93);
                        return 0;
                }
-               int status = scsi_receive_data (scsi, &v);
+               int status = scsi_receive_data (wd->scsi, &v);
 #if WD33C93_DEBUG_PIO
-               write_log (_T("%s WD_DATA READ %02x %d/%d\n"), WD33C93, v, scsi->offset, scsi->data_len);
+               write_log (_T("%s WD_DATA READ %02x %d/%d\n"), WD33C93, v, wd->scsi->offset, wd->scsi->data_len);
 #endif
-               if (wd_dataoffset < sizeof wd_data)
-                       wd_data[wd_dataoffset] = v;
-               wd_dataoffset++;
-               decreasetc ();
-               wdregs[sasr] = v;
-               wd_data_avail = 1;
-               if (status || gettc () == 0) {
-                       wd_data_avail = 0;
-                       write_comm_pipe_u32 (&requests, makecmd (scsi, 1, 0), 1);
+               if (wd->wd_dataoffset < sizeof wd->wd_data)
+                       wd->wd_data[wd->wd_dataoffset] = v;
+               wd->wd_dataoffset++;
+               decreasetc (wd);
+               wd->wdregs[wd->sasr] = v;
+               wd->wd_data_avail = 1;
+               if (status || gettc (wd) == 0) {
+                       wd->wd_data_avail = 0;
+                       write_comm_pipe_u32 (&wd->requests, makecmd (wd->scsi, 1, 0), 1);
                }
-       } else if (sasr == WD_SCSI_STATUS) {
+       } else if (wd->sasr == WD_SCSI_STATUS) {
                uae_int_requested &= ~2;
-               auxstatus &= ~0x80;
-               cdtv_scsi_clear_int ();
-               dmac_istr &= ~ISTR_INTS;
+               wd->auxstatus &= ~0x80;
+               if (wd->cdtv)
+                       cdtv_scsi_clear_int ();
+               wd->dmac_istr &= ~ISTR_INTS;
 #if 0
-               if (wdregs[WD_COMMAND_PHASE] == 0x10) {
-                       wdregs[WD_COMMAND_PHASE] = 0x11;
-                       wd_phase = CSR_SRV_REQ | PHS_MESS_OUT;
-                       set_status (wd_phase, 1);
+               if (wd->wdregs[WD_COMMAND_PHASE] == 0x10) {
+                       wd->wdregs[WD_COMMAND_PHASE] = 0x11;
+                       wd->wd_phase = CSR_SRV_REQ | PHS_MESS_OUT;
+                       set_status (wd, wd->wd_phase, 1);
                }
 #endif
-       } else if (sasr == WD_AUXILIARY_STATUS) {
-               v = wdscsi_getauxstatus ();
+       } else if (wd->sasr == WD_AUXILIARY_STATUS) {
+               v = wdscsi_getauxstatus (wd);
        }
-       incsasr (0);
+       incsasr (wd, 0);
 #if WD33C93_DEBUG > 1
        if (WD33C93_DEBUG > 3 || osasr != WD_DATA)
                write_log (_T("R %s REG %02X = %02X (%d) PC=%08X\n"), WD33C93, osasr, v, v, M68K_GETPC);
@@ -1016,19 +1009,19 @@ uae_u8 wdscsi_get (void)
        return v;
 }
 
-static uae_u32 dmac_read_word (uaecptr addr)
+static uae_u32 dmac_read_word (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v = 0;
 
        if (addr < 0x40)
-               return (dmacmemory[addr] << 8) | dmacmemory[addr + 1];
+               return (wd->dmacmemory[addr] << 8) | wd->dmacmemory[addr + 1];
        if (addr >= ROM_OFFSET) {
-               if (rom) {
-                       int off = addr & rom_mask;
-                       if (rombankswitcher && (addr & 0xffe0) == ROM_OFFSET)
-                               rombank = (addr & 0x02) >> 1;
-                       off += rombank * rom_size;
-                       return (rom[off] << 8) | rom[off + 1];
+               if (wd->rom) {
+                       int off = addr & wd->rom_mask;
+                       if (wd->rombankswitcher && (addr & 0xffe0) == ROM_OFFSET)
+                               wd->rombank = (addr & 0x02) >> 1;
+                       off += wd->rombank * wd->rom_size;
+                       return (wd->rom[off] << 8) | wd->rom[off + 1];
                }
                return 0;
        }
@@ -1037,21 +1030,21 @@ static uae_u32 dmac_read_word (uaecptr addr)
        switch (addr)
        {
        case 0x40:
-               v = dmac_istr;
+               v = wd->dmac_istr;
                if (v)
                        v |= ISTR_INT_P;
-               dmac_istr &= ~0xf;
+               wd->dmac_istr &= ~0xf;
                break;
        case 0x42:
-               v = dmac_cntr;
+               v = wd->dmac_cntr;
                break;
        case 0x80:
-               if (old_dmac)
-                       v = (dmac_wtc >> 16) & 0xffff;
+               if (wd->old_dmac)
+                       v = (wd->dmac_wtc >> 16) & 0xffff;
                break;
        case 0x82:
-               if (old_dmac)
-                       v = dmac_wtc & 0xffff;
+               if (wd->old_dmac)
+                       v = wd->dmac_wtc & 0xffff;
                break;
        case 0xc0:
                v = 0xf8 | (1 << 0) | (1 << 1) | (1 << 2); // bits 0-2 = dip-switches
@@ -1067,19 +1060,19 @@ static uae_u32 dmac_read_word (uaecptr addr)
                v = 0xffff;
                break;
        case 0xe0:
-               if (dmac_dma <= 0)
-                       scsi_dmac_start_dma ();
+               if (wd->dmac_dma <= 0)
+                       scsi_dmac_start_dma (wd);
                break;
        case 0xe2:
-               scsi_dmac_stop_dma ();
+               scsi_dmac_stop_dma (wd);
                break;
        case 0xe4:
-               dmac_cint ();
+               dmac_cint (wd);
                break;
        case 0xe8:
                /* FLUSH (new only) */
-               if (!old_dmac && dmac_dma > 0)
-                       dmac_istr |= ISTR_FE_FLG;
+               if (!wd->old_dmac && wd->dmac_dma > 0)
+                       wd->dmac_istr |= ISTR_FE_FLG;
                break;
        }
 #if A2091_DEBUG_IO > 0
@@ -1088,19 +1081,19 @@ static uae_u32 dmac_read_word (uaecptr addr)
        return v;
 }
 
-static uae_u32 dmac_read_byte (uaecptr addr)
+static uae_u32 dmac_read_byte (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v = 0;
 
        if (addr < 0x40)
-               return dmacmemory[addr];
+               return wd->dmacmemory[addr];
        if (addr >= ROM_OFFSET) {
-               if (rom) {
-                       int off = addr & rom_mask;
-                       if (rombankswitcher && (addr & 0xffe0) == ROM_OFFSET)
-                               rombank = (addr & 0x02) >> 1;
-                       off += rombank * rom_size;
-                       return rom[off];
+               if (wd->rom) {
+                       int off = addr & wd->rom_mask;
+                       if (wd->rombankswitcher && (addr & 0xffe0) == ROM_OFFSET)
+                               wd->rombank = (addr & 0x02) >> 1;
+                       off += wd->rombank * wd->rom_size;
+                       return wd->rom[off];
                }
                return 0;
        }
@@ -1108,13 +1101,13 @@ static uae_u32 dmac_read_byte (uaecptr addr)
        switch (addr)
        {
        case 0x91:
-               v = wdscsi_getauxstatus ();
+               v = wdscsi_getauxstatus (wd);
                break;
        case 0x93:
-               v = wdscsi_get ();
+               v = wdscsi_get (wd);
                break;
        default:
-               v = dmac_read_word (addr);
+               v = dmac_read_word (wd, addr);
                if (!(addr & 1))
                        v >>= 8;
                break;
@@ -1125,7 +1118,7 @@ static uae_u32 dmac_read_byte (uaecptr addr)
        return v;
 }
 
-static void dmac_write_word (uaecptr addr, uae_u32 b)
+static void dmac_write_word (struct wd_state *wd, uaecptr addr, uae_u32 b)
 {
        if (addr < 0x40)
                return;
@@ -1140,50 +1133,50 @@ static void dmac_write_word (uaecptr addr, uae_u32 b)
        switch (addr)
        {
        case 0x42:
-               dmac_cntr = b;
-               if (dmac_cntr & CNTR_PREST)
-                       dmac_reset ();
+               wd->dmac_cntr = b;
+               if (wd->dmac_cntr & CNTR_PREST)
+                       dmac_reset (wd);
                break;
        case 0x80:
-               dmac_wtc &= 0x0000ffff;
-               dmac_wtc |= b << 16;
+               wd->dmac_wtc &= 0x0000ffff;
+               wd->dmac_wtc |= b << 16;
                break;
        case 0x82:
-               dmac_wtc &= 0xffff0000;
-               dmac_wtc |= b & 0xffff;
+               wd->dmac_wtc &= 0xffff0000;
+               wd->dmac_wtc |= b & 0xffff;
                break;
        case 0x84:
-               dmac_acr &= 0x0000ffff;
-               dmac_acr |= b << 16;
+               wd->dmac_acr &= 0x0000ffff;
+               wd->dmac_acr |= b << 16;
                break;
        case 0x86:
-               dmac_acr &= 0xffff0000;
-               dmac_acr |= b & 0xfffe;
-               if (old_dmac)
-                       dmac_acr &= ~3;
+               wd->dmac_acr &= 0xffff0000;
+               wd->dmac_acr |= b & 0xfffe;
+               if (wd->old_dmac)
+                       wd->dmac_acr &= ~3;
                break;
        case 0x8e:
-               dmac_dawr = b;
+               wd->dmac_dawr = b;
                break;
                break;
        case 0xe0:
-               if (dmac_dma <= 0)
-                       scsi_dmac_start_dma ();
+               if (wd->dmac_dma <= 0)
+                       scsi_dmac_start_dma (wd);
                break;
        case 0xe2:
-               scsi_dmac_stop_dma ();
+               scsi_dmac_stop_dma (wd);
                break;
        case 0xe4:
-               dmac_cint ();
+               dmac_cint (wd);
                break;
        case 0xe8:
                /* FLUSH */
-               dmac_istr |= ISTR_FE_FLG;
+               wd->dmac_istr |= ISTR_FE_FLG;
                break;
        }
 }
 
-static void dmac_write_byte (uaecptr addr, uae_u32 b)
+static void dmac_write_byte (struct wd_state *wd, uaecptr addr, uae_u32 b)
 {
        if (addr < 0x40)
                return;
@@ -1197,101 +1190,103 @@ static void dmac_write_byte (uaecptr addr, uae_u32 b)
        switch (addr)
        {
        case 0x91:
-               wdscsi_sasr (b);
+               wdscsi_sasr (wd, b);
                break;
        case 0x93:
-               wdscsi_put (b);
+               wdscsi_put (wd, b);
                break;
        default:
                if (addr & 1)
-                       dmac_write_word (addr, b);
+                       dmac_write_word (wd, addr, b);
                else
-                       dmac_write_word (addr, b << 8);
+                       dmac_write_word (wd, addr, b << 8);
        }
 }
 
-
-static uae_u32 REGPARAM2 dmac_lget (uaecptr addr)
+static uae_u32 REGPARAM2 dmac_lget (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
        addr &= 65535;
-       v = dmac_read_word (addr) << 16;
-       v |= dmac_read_word (addr + 2) & 0xffff;
+       v = dmac_read_word (wd, addr) << 16;
+       v |= dmac_read_word (wd, addr + 2) & 0xffff;
        return v;
 }
 
-static uae_u32 REGPARAM2 dmac_wget (uaecptr addr)
+static uae_u32 REGPARAM2 dmac_wget (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
        addr &= 65535;
-       v = dmac_read_word (addr);
+       v = dmac_read_word (wd, addr);
        return v;
 }
 
-static uae_u32 REGPARAM2 dmac_bget (uaecptr addr)
+static uae_u32 REGPARAM2 dmac_bget (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
        addr &= 65535;
-       v = dmac_read_byte (addr);
-       if (!configured)
-               return v;
+       v = dmac_read_byte (wd, addr);
        return v;
 }
 
-static void REGPARAM2 dmac_lput (uaecptr addr, uae_u32 l)
+static void REGPARAM2 dmac_lput (struct wd_state *wd, uaecptr addr, uae_u32 l)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        addr &= 65535;
-       dmac_write_word (addr + 0, l >> 16);
-       dmac_write_word (addr + 2, l);
+       dmac_write_word (wd, addr + 0, l >> 16);
+       dmac_write_word (wd, addr + 2, l);
 }
 
-static void REGPARAM2 dmac_wput (uaecptr addr, uae_u32 w)
+static void REGPARAM2 dmac_wput (struct wd_state *wd, uaecptr addr, uae_u32 w)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        addr &= 65535;
-       dmac_write_word (addr, w);
+       dmac_write_word (wd, addr, w);
 }
 
-static void REGPARAM2 dmac_bput (uaecptr addr, uae_u32 b)
+extern addrbank dmaca2091_bank;
+extern addrbank dmaca2091_2_bank;
+
+static void REGPARAM2 dmac_bput (struct wd_state *wd, uaecptr addr, uae_u32 b)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        b &= 0xff;
        addr &= 65535;
-       if (addr == 0x48 && !configured) {
-               map_banks (&dmaca2091_bank, b, 0x10000 >> 16, 0x10000);
-               write_log (_T("A590/A2091 Z2 autoconfigured at %02X0000\n"), b);
-               configured = 1;
-               expamem_next ();
-               return;
-       }
-       if (addr == 0x4c && !configured) {
-               write_log (_T("A590/A2091 DMAC AUTOCONFIG SHUT-UP!\n"));
-               configured = 1;
-               expamem_next ();
-               return;
+       if (wd->autoconfig) {
+               if (addr == 0x48 && !wd->configured) {
+                       map_banks (wd == &wd_a2091 ? &dmaca2091_bank : &dmaca2091_2_bank, b, 0x10000 >> 16, 0x10000);
+                       write_log (_T("%s Z2 autoconfigured at %02X0000\n"), wd->name, b);
+                       wd->configured = 1;
+                       expamem_next ();
+                       return;
+               }
+               if (addr == 0x4c && !wd->configured) {
+                       write_log (_T("%s DMAC AUTOCONFIG SHUT-UP!\n"), wd->name);
+                       wd->configured = 1;
+                       expamem_next ();
+                       return;
+               }
+               if (!wd->configured)
+                       return;
        }
-       if (!configured)
-               return;
-       dmac_write_byte (addr, b);
+       dmac_write_byte (wd, addr, b);
 }
 
-static uae_u32 REGPARAM2 dmac_wgeti (uaecptr addr)
+static uae_u32 REGPARAM2 dmac_wgeti (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v = 0xffff;
 #ifdef JIT
@@ -1299,45 +1294,131 @@ static uae_u32 REGPARAM2 dmac_wgeti (uaecptr addr)
 #endif
        addr &= 65535;
        if (addr >= ROM_OFFSET)
-               v = (rom[addr & rom_mask] << 8) | rom[(addr + 1) & rom_mask];
+               v = (wd->rom[addr & wd->rom_mask] << 8) | wd->rom[(addr + 1) & wd->rom_mask];
        return v;
 }
-static uae_u32 REGPARAM2 dmac_lgeti (uaecptr addr)
+static uae_u32 REGPARAM2 dmac_lgeti (struct wd_state *wd, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
        addr &= 65535;
-       v = (dmac_wgeti (addr) << 16) | dmac_wgeti (addr + 2);
+       v = (dmac_wgeti (wd, addr) << 16) | dmac_wgeti (wd, addr + 2);
        return v;
 }
 
-static int REGPARAM2 dmac_check (uaecptr addr, uae_u32 size)
+static int REGPARAM2 dmac_check (struct wd_state *wd, uaecptr addr, uae_u32 size)
 {
        return 1;
 }
 
-static uae_u8 *REGPARAM2 dmac_xlate (uaecptr addr)
+static uae_u8 *REGPARAM2 dmac_xlate (struct wd_state *wd, uaecptr addr)
 {
        addr &= 0xffff;
-       addr += rombank * rom_size;
+       addr += wd->rombank * wd->rom_size;
        if (addr >= 0x8000)
                addr = 0x8000;
-       return rom + addr;
+       return wd->rom + addr;
+}
+
+static uae_u8 *REGPARAM2 dmac_a2091_xlate (uaecptr addr)
+{
+       return dmac_xlate(&wd_a2091, addr);
+}
+static int REGPARAM2 dmac_a2091_check (uaecptr addr, uae_u32 size)
+{
+       return dmac_check(&wd_a2091, addr, size);
+}
+static uae_u32 REGPARAM2 dmac_a2091_lgeti (uaecptr addr)
+{
+       return dmac_lgeti(&wd_a2091, addr);
+}
+static uae_u32 REGPARAM2 dmac_a2091_wgeti (uaecptr addr)
+{
+       return dmac_wgeti(&wd_a2091, addr);
+}
+static uae_u32 REGPARAM2 dmac_a2091_bget (uaecptr addr)
+{
+       return dmac_bget(&wd_a2091, addr);
+}
+static uae_u32 REGPARAM2 dmac_a2091_wget (uaecptr addr)
+{
+       return dmac_wget(&wd_a2091, addr);
+}
+static uae_u32 REGPARAM2 dmac_a2091_lget (uaecptr addr)
+{
+       return dmac_lget(&wd_a2091, addr);
+}
+static void REGPARAM2 dmac_a2091_bput (uaecptr addr, uae_u32 b)
+{
+       dmac_bput(&wd_a2091, addr, b);
+}
+static void REGPARAM2 dmac_a2091_wput (uaecptr addr, uae_u32 b)
+{
+       dmac_wput(&wd_a2091, addr, b);
+}
+static void REGPARAM2 dmac_a2091_lput (uaecptr addr, uae_u32 b)
+{
+       dmac_lput(&wd_a2091, addr, b);
+}
+
+static uae_u8 *REGPARAM2 dmac_a20912_xlate (uaecptr addr)
+{
+       return dmac_xlate(&wd_a2091_2, addr);
+}
+static int REGPARAM2 dmac_a20912_check (uaecptr addr, uae_u32 size)
+{
+       return dmac_check(&wd_a2091_2, addr, size);
+}
+static uae_u32 REGPARAM2 dmac_a20912_lgeti (uaecptr addr)
+{
+       return dmac_lgeti(&wd_a2091_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_a20912_wgeti (uaecptr addr)
+{
+       return dmac_wgeti(&wd_a2091_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_a20912_bget (uaecptr addr)
+{
+       return dmac_bget(&wd_a2091_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_a20912_wget (uaecptr addr)
+{
+       return dmac_wget(&wd_a2091_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_a20912_lget (uaecptr addr)
+{
+       return dmac_lget(&wd_a2091_2, addr);
+}
+static void REGPARAM2 dmac_a20912_bput (uaecptr addr, uae_u32 b)
+{
+       dmac_bput(&wd_a2091_2, addr, b);
+}
+static void REGPARAM2 dmac_a20912_wput (uaecptr addr, uae_u32 b)
+{
+       dmac_wput(&wd_a2091_2, addr, b);
+}
+static void REGPARAM2 dmac_a20912_lput (uaecptr addr, uae_u32 b)
+{
+       dmac_lput(&wd_a2091_2, addr, b);
 }
 
 addrbank dmaca2091_bank = {
-       dmac_lget, dmac_wget, dmac_bget,
-       dmac_lput, dmac_wput, dmac_bput,
-       dmac_xlate, dmac_check, NULL, _T("A2091/A590"),
-       dmac_lgeti, dmac_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       dmac_a2091_lget, dmac_a2091_wget, dmac_a2091_bget,
+       dmac_a2091_lput, dmac_a2091_wput, dmac_a2091_bput,
+       dmac_a2091_xlate, dmac_a2091_check, NULL, _T("A2091/A590"),
+       dmac_a2091_lgeti, dmac_a2091_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+addrbank dmaca2091_2_bank = {
+       dmac_a20912_lget, dmac_a20912_wget, dmac_a20912_bget,
+       dmac_a20912_lput, dmac_a20912_wput, dmac_a20912_bput,
+       dmac_a20912_xlate, dmac_a20912_check, NULL, _T("A2091/A590 #2"),
+       dmac_a20912_lgeti, dmac_a20912_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-static void mbdmac_write_word (uae_u32 addr, uae_u32 val)
+static void mbdmac_write_word (struct wd_state *wd, uae_u32 addr, uae_u32 val)
 {
-       if (currprefs.cs_mbdmac > 1)
-               return;
 #if A3000_DEBUG_IO > 1
        write_log (_T("DMAC_WWRITE %08X=%04X PC=%08X\n"), addr, val & 0xffff, M68K_GETPC);
 #endif
@@ -1345,56 +1426,54 @@ static void mbdmac_write_word (uae_u32 addr, uae_u32 val)
        switch (addr)
        {
        case 0x02:
-               dmac_dawr = val;
+               wd->dmac_dawr = val;
                break;
        case 0x04:
-               dmac_wtc &= 0x0000ffff;
-               dmac_wtc |= val << 16;
+               wd->dmac_wtc &= 0x0000ffff;
+               wd->dmac_wtc |= val << 16;
                break;
        case 0x06:
-               dmac_wtc &= 0xffff0000;
-               dmac_wtc |= val & 0xffff;
+               wd->dmac_wtc &= 0xffff0000;
+               wd->dmac_wtc |= val & 0xffff;
                break;
        case 0x0a:
-               dmac_cntr = val;
-               if (dmac_cntr & SCNTR_PREST)
-                       dmac_reset ();
+               wd->dmac_cntr = val;
+               if (wd->dmac_cntr & SCNTR_PREST)
+                       dmac_reset (wd);
                break;
        case 0x0c:
-               dmac_acr &= 0x0000ffff;
-               dmac_acr |= val << 16;
+               wd->dmac_acr &= 0x0000ffff;
+               wd->dmac_acr |= val << 16;
                break;
        case 0x0e:
-               dmac_acr &= 0xffff0000;
-               dmac_acr |= val & 0xfffe;
+               wd->dmac_acr &= 0xffff0000;
+               wd->dmac_acr |= val & 0xfffe;
                break;
        case 0x12:
-               if (dmac_dma <= 0)
-                       scsi_dmac_start_dma ();
+               if (wd->dmac_dma <= 0)
+                       scsi_dmac_start_dma (wd);
                break;
        case 0x16:
-               if (dmac_dma) {
+               if (wd->dmac_dma) {
                        /* FLUSH */
-                       dmac_istr |= ISTR_FE_FLG;
-                       dmac_dma = 0;
+                       wd->dmac_istr |= ISTR_FE_FLG;
+                       wd->dmac_dma = 0;
                }
                break;
        case 0x1a:
-               dmac_cint();
+               dmac_cint(wd);
                break;
        case 0x1e:
                /* ISTR */
                break;
        case 0x3e:
-               scsi_dmac_stop_dma ();
+               scsi_dmac_stop_dma (wd);
                break;
        }
 }
 
-static void mbdmac_write_byte (uae_u32 addr, uae_u32 val)
+static void mbdmac_write_byte (struct wd_state *wd, uae_u32 addr, uae_u32 val)
 {
-       if (currprefs.cs_mbdmac > 1)
-               return;
 #if A3000_DEBUG_IO > 1
        write_log (_T("DMAC_BWRITE %08X=%02X PC=%08X\n"), addr, val & 0xff, M68K_GETPC);
 #endif
@@ -1403,73 +1482,70 @@ static void mbdmac_write_byte (uae_u32 addr, uae_u32 val)
        {
 
        case 0x41:
-               sasr = val;
+               wd->sasr = val;
                break;
        case 0x49:
-               sasr = val;
+               wd->sasr = val;
                break;
        case 0x43:
        case 0x47:
-               wdscsi_put (val);
+               wdscsi_put (wd, val);
                break;
        default:
                if (addr & 1)
-                       mbdmac_write_word (addr, val);
+                       mbdmac_write_word (wd, addr, val);
                else
-                       mbdmac_write_word (addr, val << 8);
+                       mbdmac_write_word (wd, addr, val << 8);
        }
 }
 
-static uae_u32 mbdmac_read_word (uae_u32 addr)
+static uae_u32 mbdmac_read_word (struct wd_state *wd, uae_u32 addr)
 {
 #if A3000_DEBUG_IO > 1
        uae_u32 vaddr = addr;
 #endif
        uae_u32 v = 0xffffffff;
 
-       if (currprefs.cs_mbdmac > 1)
-               return 0;
-
        addr &= 0xfffe;
        switch (addr)
        {
        case 0x02:
-               v = dmac_dawr;
+               v = wd->dmac_dawr;
                break;
        case 0x04:
        case 0x06:
                v = 0xffff;
                break;
        case 0x0a:
-               v = dmac_cntr;
+               v = wd->dmac_cntr;
                break;
        case 0x0c:
-               v = dmac_acr >> 16;
+               v = wd->dmac_acr >> 16;
                break;
        case 0x0e:
-               v = dmac_acr;
+               v = wd->dmac_acr;
                break;
        case 0x12:
-               if (dmac_dma <= 0)
-                       scsi_dmac_start_dma ();
+               if (wd->dmac_dma <= 0)
+                       scsi_dmac_start_dma (wd);
                v = 0;
                break;
        case 0x1a:
-               dmac_cint ();
+               dmac_cint (wd);
                v = 0;
                break;;
        case 0x1e:
-               v = dmac_istr;
+               v = wd->dmac_istr;
                if (v & ISTR_INTS)
                        v |= ISTR_INT_P;
-               dmac_istr &= ~15;
-               if (!dmac_dma)
+               wd->dmac_istr &= ~15;
+               if (!wd->dmac_dma)
                        v |= ISTR_FE_FLG;
                break;
        case 0x3e:
-               if (dmac_dma) {
-                       scsi_dmac_stop_dma ();
-                       dmac_istr |= ISTR_FE_FLG;
+               if (wd->dmac_dma) {
+                       scsi_dmac_stop_dma (wd);
+                       wd->dmac_istr |= ISTR_FE_FLG;
                }
                v = 0;
                break;
@@ -1480,29 +1556,26 @@ static uae_u32 mbdmac_read_word (uae_u32 addr)
        return v;
 }
 
-static uae_u32 mbdmac_read_byte (uae_u32 addr)
+static uae_u32 mbdmac_read_byte (struct wd_state *wd, uae_u32 addr)
 {
 #if A3000_DEBUG_IO > 1
        uae_u32 vaddr = addr;
 #endif
        uae_u32 v = 0xffffffff;
 
-       if (currprefs.cs_mbdmac > 1)
-               return 0;
-
        addr &= 0xffff;
        switch (addr)
        {
        case 0x41:
        case 0x49:
-               v = wdscsi_getauxstatus ();
+               v = wdscsi_getauxstatus (wd);
                break;
        case 0x43:
        case 0x47:
-               v = wdscsi_get ();
+               v = wdscsi_get (wd);
                break;
        default:
-               v = mbdmac_read_word (addr);
+               v = mbdmac_read_word (wd, addr);
                if (!(addr & 1))
                        v >>= 8;
                break;
@@ -1527,8 +1600,8 @@ static uae_u32 REGPARAM2 mbdmac_lget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       v =  mbdmac_read_word (addr + 0) << 16;
-       v |= mbdmac_read_word (addr + 2) << 0;
+       v =  mbdmac_read_word (&wd_a3000, addr + 0) << 16;
+       v |= mbdmac_read_word (&wd_a3000, addr + 2) << 0;
        return v;
 }
 static uae_u32 REGPARAM2 mbdmac_wget (uaecptr addr)
@@ -1537,7 +1610,7 @@ static uae_u32 REGPARAM2 mbdmac_wget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       v =  mbdmac_read_word (addr);
+       v =  mbdmac_read_word (&wd_a3000, addr);
        return v;
 }
 static uae_u32 REGPARAM2 mbdmac_bget (uaecptr addr)
@@ -1545,7 +1618,7 @@ static uae_u32 REGPARAM2 mbdmac_bget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       return mbdmac_read_byte (addr);
+       return mbdmac_read_byte (&wd_a3000, addr);
 }
 static void REGPARAM2 mbdmac_lput (uaecptr addr, uae_u32 l)
 {
@@ -1554,10 +1627,10 @@ static void REGPARAM2 mbdmac_lput (uaecptr addr, uae_u32 l)
 #endif
        if ((addr & 0xffff) == 0x40) {
                // long write to 0x40 = write byte to SASR
-               mbdmac_write_byte (0x41, l);
+               mbdmac_write_byte (&wd_a3000, 0x41, l);
        } else {
-               mbdmac_write_word (addr + 0, l >> 16);
-               mbdmac_write_word (addr + 2, l >> 0);
+               mbdmac_write_word (&wd_a3000, addr + 0, l >> 16);
+               mbdmac_write_word (&wd_a3000, addr + 2, l >> 0);
        }
 }
 static void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 w)
@@ -1565,14 +1638,14 @@ static void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 w)
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       mbdmac_write_word (addr + 0, w);
+       mbdmac_write_word (&wd_a3000, addr + 0, w);
 }
 static void REGPARAM2 mbdmac_bput (uaecptr addr, uae_u32 b)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       mbdmac_write_byte (addr, b);
+       mbdmac_write_byte (&wd_a3000, addr, b);
 }
 
 addrbank mbdmac_a3000_bank = {
@@ -1582,23 +1655,24 @@ addrbank mbdmac_a3000_bank = {
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-static void ew (int addr, uae_u32 value)
+static void ew (struct wd_state *wd, int addr, uae_u32 value)
 {
        addr &= 0xffff;
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
-               dmacmemory[addr] = (value & 0xf0);
-               dmacmemory[addr + 2] = (value & 0x0f) << 4;
+               wd->dmacmemory[addr] = (value & 0xf0);
+               wd->dmacmemory[addr + 2] = (value & 0x0f) << 4;
        } else {
-               dmacmemory[addr] = ~(value & 0xf0);
-               dmacmemory[addr + 2] = ~((value & 0x0f) << 4);
+               wd->dmacmemory[addr] = ~(value & 0xf0);
+               wd->dmacmemory[addr + 2] = ~((value & 0x0f) << 4);
        }
 }
 
-static void *scsi_thread (void *null)
+static void *scsi_thread (void *wdv)
 {
+       struct wd_state *wd = (struct wd_state*)wdv;
        for (;;) {
-               uae_u32 v = read_comm_pipe_u32_blocking (&requests);
-               if (scsi_thread_running == 0 || v == 0xfffffff)
+               uae_u32 v = read_comm_pipe_u32_blocking (&wd->requests);
+               if (wd->scsi_thread_running == 0 || v == 0xfffffff)
                        break;
                int cmd = v & 0x7f;
                int msg = (v >> 8) & 0xff;
@@ -1610,48 +1684,56 @@ static void *scsi_thread (void *null)
                        switch (cmd)
                        {
                        case WD_CMD_RESET:
-                               wd_cmd_reset (true);
+                               wd_cmd_reset (wd, true);
                                break;
                        case WD_CMD_ABORT:
-                               wd_cmd_abort ();
+                               wd_cmd_abort (wd);
                                break;
                        case WD_CMD_SEL:
-                               wd_cmd_sel (false);
+                               wd_cmd_sel (wd, false);
                                break;
                        case WD_CMD_SEL_ATN:
-                               wd_cmd_sel (true);
+                               wd_cmd_sel (wd, true);
                                break;
                        case WD_CMD_SEL_ATN_XFER:
-                               wd_cmd_sel_xfer (true);
+                               wd_cmd_sel_xfer (wd, true);
                                break;
                        case WD_CMD_SEL_XFER:
-                               wd_cmd_sel_xfer (false);
+                               wd_cmd_sel_xfer (wd, false);
                                break;
                        case WD_CMD_TRANS_INFO:
-                               wd_cmd_trans_info ();
+                               wd_cmd_trans_info (wd);
                                break;
                        default:
-                               wd_busy = false;
+                               wd->wd_busy = false;
                                write_log (_T("%s unimplemented/unknown command %02X\n"), WD33C93, cmd);
-                               set_status (CSR_INVALID, 10);
+                               set_status (wd, CSR_INVALID, 10);
                                break;
                        }
                } else if (msg == 1) {
-                       wd_do_transfer_in ();
+                       wd_do_transfer_in (wd);
                } else if (msg == 2) {
-                       wd_do_transfer_out ();
+                       wd_do_transfer_out (wd);
                }
        }
-       scsi_thread_running = -1;
+       wd->scsi_thread_running = -1;
        return 0;
 }
 
-void init_scsi (void)
+void init_scsi (struct wd_state *wd)
 {
-       if (!scsi_thread_running) {
-               scsi_thread_running = 1;
-               init_comm_pipe (&requests, 100, 1);
-               uae_start_thread (_T("scsi"), scsi_thread, 0, NULL);
+       wd->configured = 0;
+       wd->enabled = true;
+       wd->wd_used = 0;
+       wd->wd33c93_ver = 1;
+       if (wd == &wd_cdtv) {
+               wd->cdtv = true;
+               wd->name = _T("CDTV");
+       }
+       if (!wd->scsi_thread_running) {
+               wd->scsi_thread_running = 1;
+               init_comm_pipe (&wd->requests, 100, 1);
+               uae_start_thread (_T("scsi"), scsi_thread, wd, NULL);
        }
 }
 
@@ -1663,11 +1745,11 @@ static void freescsi (struct scsi_data *sd)
        scsi_free (sd);
 }
 
-int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
+int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
 {
-       init_scsi ();
-       freescsi (scsis[ch]);
-       scsis[ch] = NULL;
+       init_scsi (wd);
+       freescsi (wd->scsis[ch]);
+       wd->scsis[ch] = NULL;
        if (!hfd) {
                hfd = xcalloc (struct hd_hardfiledata, 1);
                memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
@@ -1675,44 +1757,44 @@ int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info
        if (!hdf_hd_open (hfd))
                return 0;
        hfd->ansi_version = scsi_level;
-       scsis[ch] = scsi_alloc_hd (ch, hfd);
-       return scsis[ch] ? 1 : 0;
+       wd->scsis[ch] = scsi_alloc_hd (ch, hfd);
+       return wd->scsis[ch] ? 1 : 0;
 }
 
-int add_scsi_cd (int ch, int unitnum)
+int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum)
 {
-       init_scsi ();
+       init_scsi (wd);
        device_func_init (0);
-       freescsi (scsis[ch]);
-       scsis[ch] = scsi_alloc_cd (ch, unitnum, false);
-       return scsis[ch] ? 1 : 0;
+       freescsi (wd->scsis[ch]);
+       wd->scsis[ch] = scsi_alloc_cd (ch, unitnum, false);
+       return wd->scsis[ch] ? 1 : 0;
 }
 
-int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly)
+int add_wd_scsi_tape (struct wd_state *wd, int ch, const TCHAR *tape_directory, bool readonly)
 {
-       init_scsi ();
-       freescsi (scsis[ch]);
-       scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
-       return scsis[ch] ? 1 : 0;
+       init_scsi (wd);
+       freescsi (wd->scsis[ch]);
+       wd->scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
+       return wd->scsis[ch] ? 1 : 0;
 }
 
-static void freenativescsi (void)
+static void freenativescsi (struct wd_state *wd)
 {
        int i;
        for (i = 0; i < 7; i++) {
-               freescsi (scsis[i]);
-               scsis[i] = NULL;
+               freescsi (wd->scsis[i]);
+               wd->scsis[i] = NULL;
        }
 }
 
-static void addnativescsi (void)
+static void addnativescsi (struct wd_state *wd)
 {
        int i, j;
        int devices[MAX_TOTAL_SCSI_DEVICES];
        int types[MAX_TOTAL_SCSI_DEVICES];
        struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
 
-       freenativescsi ();
+       freenativescsi (wd);
        i = 0;
        while (i < MAX_TOTAL_SCSI_DEVICES) {
                types[i] = -1;
@@ -1743,8 +1825,8 @@ static void addnativescsi (void)
        }
        i = 0; j = 0;
        while (devices[i] >= 0 && j < 7) {
-               if (scsis[j] == NULL) {
-                       scsis[j] = scsi_alloc_native(j, devices[i]);
+               if (wd->scsis[j] == NULL) {
+                       wd->scsis[j] = scsi_alloc_native(j, devices[i]);
                        write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
                        i++;
                }
@@ -1754,86 +1836,114 @@ static void addnativescsi (void)
 
 int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci)
 {
-       init_scsi ();
+       struct wd_state *wd = &wd_a3000;
+       init_scsi (wd);
        if (ci->type == UAEDEV_CD)
-               return add_scsi_cd (ch, ci->device_emu_unit);
+               return add_wd_scsi_cd (wd, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+               return add_wd_scsi_tape (wd, ch, ci->rootdir, ci->readonly);
        else
-               return add_scsi_hd (ch, NULL, ci, 2);
+               return add_wd_scsi_hd (wd, ch, NULL, ci, 2);
 }
 
 void a3000scsi_reset (void)
 {
-       init_scsi ();
+       struct wd_state *wd = &wd_a3000;
+       init_scsi (wd);
+       wd->configured = -1;
+       wd->superdmac = 1;
        map_banks (&mbdmac_a3000_bank, 0xDD, 1, 0);
-       wd_cmd_reset (false);
+       wd_cmd_reset (wd, false);
+       wd->name = _T("A3000");
 }
 
 void a3000scsi_free (void)
 {
-       freenativescsi ();
-       if (scsi_thread_running > 0) {
-               scsi_thread_running = 0;
-               write_comm_pipe_u32 (&requests, 0xffffffff, 1);
-               while(scsi_thread_running == 0)
+       struct wd_state *wd = &wd_a3000;
+       freenativescsi (wd);
+       if (wd->scsi_thread_running > 0) {
+               wd->scsi_thread_running = 0;
+               write_comm_pipe_u32 (&wd->requests, 0xffffffff, 1);
+               while(wd->scsi_thread_running == 0)
                        sleep_millis (10);
-               scsi_thread_running = 0;
+               wd->scsi_thread_running = 0;
        }
 }
 
-int a2091_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+int a2091_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum)
 {
+       struct wd_state *wd = wda2091[devnum];
        if (ci->type == UAEDEV_CD)
-               return add_scsi_cd (ch, ci->device_emu_unit);
+               return add_wd_scsi_cd (wd, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+               return add_wd_scsi_tape (wd, ch, ci->rootdir, ci->readonly);
        else
-               return add_scsi_hd (ch, NULL, ci, 1);
+               return add_wd_scsi_hd (wd, ch, NULL, ci, 1);
 }
 
-
+void a2091_free_device (struct wd_state *wd)
+{
+       freenativescsi (wd);
+       xfree (wd->rom);
+       wd->rom = NULL;
+}
 void a2091_free (void)
 {
-       freenativescsi ();
-       xfree (rom);
-       rom = NULL;
+       a2091_free_device(&wd_a2091);
+       a2091_free_device(&wd_a2091_2);
 }
 
-void a2091_reset (void)
+static void a2091_reset_device(struct wd_state *wd)
 {
-       configured = 0;
-       wd_used = 0;
-       superdmac = 0;
-       superdmac = currprefs.cs_mbdmac ? 1 : 0;
+       wd->configured = 0;
+       wd->wd_used = 0;
+       wd->superdmac = 0;
+       wd->wd33c93_ver = 1;
+       wd->old_dmac = 0;
        if (currprefs.scsi == 2)
-               addnativescsi ();
-       wd_cmd_reset (false);
+               addnativescsi (wd);
+       wd_cmd_reset (wd, false);
+       if (wd == &wd_a2091)
+               wd->name = _T("A2091/A590");
+       if (wd == &wd_a2091_2)
+               wd->name = _T("A2091/A590 #2");
+}
+
+void a2091_reset (void)
+{
+       a2091_reset_device(&wd_a2091);
+       a2091_reset_device(&wd_a2091_2);
 }
 
-void a2091_init (void)
+void a2091_init (int devnum)
 {
+       struct wd_state *wd = wda2091[devnum];
        int roms[6];
        int slotsize;
        struct romlist *rl;
 
-       init_scsi ();
-       configured = 0;
-       memset (dmacmemory, 0xff, sizeof dmacmemory);
-       ew (0x00, 0xc0 | 0x01 | 0x10);
+       if (!wd->enabled) {
+               expamem_next();
+               return;
+       }
+
+       wd->configured = 0;
+       wd->autoconfig = true;
+       memset (wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
+       ew (wd, 0x00, 0xc0 | 0x01 | 0x10);
        /* A590/A2091 hardware id */
-       ew (0x04, old_dmac ? 0x02 : 0x03);
+       ew (wd, 0x04, wd->old_dmac ? 0x02 : 0x03);
        /* commodore's manufacturer id */
-       ew (0x10, 0x02);
-       ew (0x14, 0x02);
+       ew (wd, 0x10, 0x02);
+       ew (wd, 0x14, 0x02);
        /* rom vector */
-       ew (0x28, ROM_VECTOR >> 8);
-       ew (0x2c, ROM_VECTOR);
+       ew (wd, 0x28, ROM_VECTOR >> 8);
+       ew (wd, 0x2c, ROM_VECTOR);
 
-       ew (0x18, 0x00); /* ser.no. Byte 0 */
-       ew (0x1c, 0x00); /* ser.no. Byte 1 */
-       ew (0x20, 0x00); /* ser.no. Byte 2 */
-       ew (0x24, 0x00); /* ser.no. Byte 3 */
+       ew (wd, 0x18, 0x00); /* ser.no. Byte 0 */
+       ew (wd, 0x1c, 0x00); /* ser.no. Byte 1 */
+       ew (wd, 0x20, 0x00); /* ser.no. Byte 2 */
+       ew (wd, 0x24, 0x00); /* ser.no. Byte 3 */
 
        roms[0] = 55; // 7.0
        roms[1] = 54; // 6.6
@@ -1842,14 +1952,14 @@ void a2091_init (void)
        roms[4] = 87;
        roms[5] = -1;
 
-       rombankswitcher = 0;
-       rombank = 0;
+       wd->rombankswitcher = 0;
+       wd->rombank = 0;
        slotsize = 65536;
-       rom = xmalloc (uae_u8, slotsize);
-       rom_size = 16384;
-       rom_mask = rom_size - 1;
+       wd->rom = xmalloc (uae_u8, slotsize);
+       wd->rom_size = 16384;
+       wd->rom_mask = wd->rom_size - 1;
        if (_tcscmp (currprefs.a2091romfile, _T(":NOROM"))) {
-               struct zfile *z = read_rom_name (currprefs.a2091romfile);
+               struct zfile *z = read_rom_name (devnum && currprefs.a2091romfile2[0] ? currprefs.a2091romfile2 : currprefs.a2091romfile);
                if (!z) {
                        rl = getromlistbyids (roms);
                        if (rl) {
@@ -1858,32 +1968,33 @@ void a2091_init (void)
                }
                if (z) {
                        write_log (_T("A590/A2091 BOOT ROM '%s'\n"), zfile_getname (z));
-                       rom_size = zfile_size (z);
-                       zfile_fread (rom, rom_size, 1, z);
+                       wd->rom_size = zfile_size (z);
+                       zfile_fread (wd->rom, wd->rom_size, 1, z);
                        zfile_fclose (z);
-                       if (rom_size == 32768) {
-                               rombankswitcher = 1;
-                               for (int i = rom_size - 1; i >= 0; i--) {
-                                       rom[i * 2 + 0] = rom[i];
-                                       rom[i * 2 + 1] = 0xff;
+                       if (wd->rom_size == 32768) {
+                               wd->rombankswitcher = 1;
+                               for (int i = wd->rom_size - 1; i >= 0; i--) {
+                                       wd->rom[i * 2 + 0] = wd->rom[i];
+                                       wd->rom[i * 2 + 1] = 0xff;
                                }
                        } else {
-                               for (int i = 1; i < slotsize / rom_size; i++)
-                                       memcpy (rom + i * rom_size, rom, rom_size);
+                               for (int i = 1; i < slotsize / wd->rom_size; i++)
+                                       memcpy (wd->rom + i * wd->rom_size, wd->rom, wd->rom_size);
                        }
-                       rom_mask = rom_size - 1;
+                       wd->rom_mask = wd->rom_size - 1;
                } else {
                        romwarning (roms);
                }
        }
-       map_banks (&dmaca2091_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
+       map_banks (wd == &wd_a2091 ? &dmaca2091_bank : &dmaca2091_2_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
 }
 
-uae_u8 *save_scsi_dmac (int *len, uae_u8 *dstptr)
+uae_u8 *save_scsi_dmac (int wdtype, int *len, uae_u8 *dstptr)
 {
+       struct wd_state *wd = wdscsi[wdtype];
        uae_u8 *dstbak, *dst;
-       
-       if (!currprefs.a2091 && !currprefs.cs_mbdmac)
+
+       if (!wd->enabled)
                return NULL;
        if (dstptr)
                dstbak = dst = dstptr;
@@ -1891,39 +2002,43 @@ uae_u8 *save_scsi_dmac (int *len, uae_u8 *dstptr)
                dstbak = dst = xmalloc (uae_u8, 1000);
 
        // model (0=original,1=rev2,2=superdmac)
-       save_u32 (currprefs.cs_mbdmac ? 2 : 1);
+       save_u32 (currprefs.cs_mbdmac == 1 ? 2 : 1);
        save_u32 (0); // reserved flags
-       save_u8 (dmac_istr);
-       save_u8 (dmac_cntr);
-       save_u32 (dmac_wtc);
-       save_u32 (dmac_acr);
-       save_u16 (dmac_dawr);
-       save_u32 (dmac_dma ? 1 : 0);
-       save_u8 (configured);
+       save_u8 (wd->dmac_istr);
+       save_u8 (wd->dmac_cntr);
+       save_u32 (wd->dmac_wtc);
+       save_u32 (wd->dmac_acr);
+       save_u16 (wd->dmac_dawr);
+       save_u32 (wd->dmac_dma ? 1 : 0);
+       save_u8 (wd->configured);
        *len = dst - dstbak;
        return dstbak;
 }
 
-uae_u8 *restore_scsi_dmac (uae_u8 *src)
+uae_u8 *restore_scsi_dmac (int wdtype, uae_u8 *src)
 {
+       struct wd_state *wd = wdscsi[wdtype];
        restore_u32 ();
        restore_u32 ();
-       dmac_istr = restore_u8 ();
-       dmac_cntr = restore_u8 ();
-       dmac_wtc = restore_u32 ();
-       dmac_acr = restore_u32 ();
-       dmac_dawr = restore_u16 ();
+       wd->dmac_istr = restore_u8 ();
+       wd->dmac_cntr = restore_u8 ();
+       wd->dmac_wtc = restore_u32 ();
+       wd->dmac_acr = restore_u32 ();
+       wd->dmac_dawr = restore_u16 ();
        restore_u32 ();
-       configured = restore_u8 ();
+       wd->configured = restore_u8 ();
        return src;
 }
 
-uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr)
+uae_u8 *save_scsi_device (int wdtype, int num, int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
        struct scsi_data *s;
+       struct wd_state *wd = wdscsi[wdtype];
 
-       s = scsis[num];
+       if (!wd->enabled)
+               return NULL;
+       s = wd->scsis[num];
        if (!s)
                return NULL;
        if (dstptr)
@@ -1964,8 +2079,9 @@ uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr)
        return dstbak;
 }
 
-uae_u8 *restore_scsi_device (uae_u8 *src)
+uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src)
 {
+       struct wd_state *wd = wdscsi[wdtype];
        int num, num2;
        struct hd_hardfiledata *hfd;
        struct scsi_data *s;
@@ -1982,7 +2098,7 @@ uae_u8 *restore_scsi_device (uae_u8 *src)
        case UAEDEV_HDF:
        case 0:
                hfd = xcalloc (struct hd_hardfiledata, 1);
-               s = scsis[num] = scsi_alloc_hd (num, hfd);
+               s = wd->scsis[num] = scsi_alloc_hd (num, hfd);
                size = restore_u64 ();
                path = restore_string ();
                _tcscpy (s->hfd->hfd.ci.rootdir, path);
@@ -1999,19 +2115,19 @@ uae_u8 *restore_scsi_device (uae_u8 *src)
                s->hfd->ansi_version = restore_u32 ();
                s->hfd->hfd.ci.blocksize = blocksize;
                if (size)
-                       add_scsi_hd (num, hfd, NULL, s->hfd->ansi_version);
+                       add_wd_scsi_hd (wd, num, hfd, NULL, s->hfd->ansi_version);
                xfree (path);
        break;
        case UAEDEV_CD:
                num2 = restore_u32 ();
-               add_scsi_cd (num, num2);
+               add_wd_scsi_cd (wd, num, num2);
        break;
        case UAEDEV_TAPE:
                num2 = restore_u32 ();
                blocksize = restore_u32 ();
                readonly = restore_u32 ();
                path = restore_string ();
-               add_scsi_tape (num, path, readonly != 0);
+               add_wd_scsi_tape (wd, num, path, readonly != 0);
                xfree (path);
        break;
        }
index 6c0b13ff1d23bc61c060efb0e447c62ddba4329f..6af45ac7302e42221b0a347e76f161d04c0881db 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -68,7 +68,7 @@ static bool debugchannel (int ch)
 
 STATIC_INLINE bool usehacks(void)
 {
-       return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0;
+       return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0 || (currprefs.cs_hacks & 4);
 }
 
 #define SINC_QUEUE_MAX_AGE 2048
index abd29d7594dbc3cc066ecf2717df5e76ec6b67e5..bdb9fababb3176fb36c519ac7dc3edd70b555eb6 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -9,8 +9,6 @@
 *
 */
 
-//#define ROMHACK
-//#define ROMHACK2
 //#define CDTV_SUB_DEBUG
 //#define CDTV_DEBUG
 //#define CDTV_DEBUG_CMD
@@ -93,13 +91,6 @@ static int cdrom_command_cnt_in;
 static uae_u8 tp_a, tp_b, tp_c, tp_ad, tp_bd, tp_cd;
 static uae_u8 tp_imask, tp_cr, tp_air, tp_ilatch, tp_ilatch2;
 
-#ifdef ROMHACK
-#define ROM_VECTOR 0x2000
-#define ROM_OFFSET 0x2000
-static int rom_size, rom_mask;
-static uae_u8 *rom;
-#endif
-
 static void do_stch (void);
 
 static void INT2 (void)
@@ -1050,7 +1041,7 @@ static void dmac_start_dma (void)
        if (!(dmac_cntr & CNTR_PDMD)) { // non-scsi dma
                write_comm_pipe_u32 (&requests, 0x0100, 1);
        } else {
-               scsi_dmac_start_dma ();
+               scsi_dmac_start_dma (&wd_cdtv);
        }
 }
 static void dmac_stop_dma (void)
@@ -1058,7 +1049,7 @@ static void dmac_stop_dma (void)
        if (!(dmac_cntr & CNTR_PDMD)) { // non-scsi dma
                ;
        } else {
-               scsi_dmac_stop_dma ();
+               scsi_dmac_stop_dma (&wd_cdtv);
        }
 }
 
@@ -1071,7 +1062,7 @@ static void checkint (void)
 {
        int irq = 0;
 
-       if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus () & 0x80)) {
+       if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus (&wd_cdtv) & 0x80)) {
                dmac_istr |= ISTR_INTS;
                if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
                        irq = 1;
@@ -1226,16 +1217,6 @@ static void do_stch (void)
        }
 }
 
-void bleh (void)
-{
-#if 0
-       cd_playing = cd_finished = cd_motor = cd_media = 1;
-       cd_isready = 0;
-       cd_playing = 0;
-       do_stch();
-#endif
-}
-
 static void cdtv_reset_int (void)
 {
        write_log (_T("CDTV: reset\n"));
@@ -1261,16 +1242,6 @@ static uae_u32 dmac_bget2 (uaecptr addr)
        if (addr >= 0xb0 && addr < 0xc0)
                return tp_bget ((addr - 0xb0) / 2);
 
-#ifdef ROMHACK
-       if (addr >= ROM_OFFSET) {
-               if (rom) {
-                       int off = addr & rom_mask;
-                       return rom[off];
-               }
-               return 0;
-       }
-#endif
-
        switch (addr)
        {
        case 0x41:
@@ -1284,11 +1255,11 @@ static uae_u32 dmac_bget2 (uaecptr addr)
                break;
        case 0x91:
                if (currprefs.cs_cdtvscsi)
-                       v = wdscsi_getauxstatus ();
+                       v = wdscsi_getauxstatus (&wd_cdtv);
                break;
        case 0x93:
                if (currprefs.cs_cdtvscsi) {
-                       v = wdscsi_get ();
+                       v = wdscsi_get (&wd_cdtv);
                        checkint ();
                }
                break;
@@ -1391,13 +1362,13 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
                break;
        case 0x91:
                if (currprefs.cs_cdtvscsi) {
-                       wdscsi_sasr (b);
+                       wdscsi_sasr (&wd_cdtv, b);
                        checkint ();
                }
                break;
        case 0x93:
                if (currprefs.cs_cdtvscsi) {
-                       wdscsi_put (b);
+                       wdscsi_put (&wd_cdtv, b);
                        checkint ();
                }
                break;
@@ -1559,11 +1530,6 @@ static uae_u32 REGPARAM2 dmac_wgeti (uaecptr addr)
        uae_u32 v = 0xffff;
 #ifdef JIT
        special_mem |= S_READ;
-#endif
-#ifdef ROMHACK
-       addr &= 65535;
-       if (addr >= ROM_OFFSET)
-               v = (rom[addr & rom_mask] << 8) | rom[(addr + 1) & rom_mask];
 #endif
        return v;
 }
@@ -1572,10 +1538,6 @@ static uae_u32 REGPARAM2 dmac_lgeti (uaecptr addr)
        uae_u32 v = 0xffff;
 #ifdef JIT
        special_mem |= S_READ;
-#endif
-#ifdef ROMHACK
-       addr &= 65535;
-       v = (dmac_wgeti(addr) << 16) | dmac_wgeti(addr + 2);
 #endif
        return v;
 }
@@ -1673,7 +1635,7 @@ uae_u8 cdtv_battram_read (int addr)
 
 int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci)
 {
-       return add_scsi_hd (ch, NULL, ci, 1);
+       return add_wd_scsi_hd (&wd_cdtv, ch, NULL, ci, 1);
 }
 
 void cdtv_free (void)
@@ -1692,47 +1654,6 @@ void cdtv_free (void)
        configured = 0;
 }
 
-
-#ifdef ROMHACK2
-static void romhack (void)
-{
-       struct zfile *z;
-       int roms[5];
-       struct romlist *rl;
-       int rom_size;
-       uae_u8 *rom, *p;
-
-       extendedkickmemory[0x558c] = 0xff;
-
-       roms[0] = 55;
-       roms[1] = 54;
-       roms[2] = 53;
-       roms[3] = -1;
-
-       rl = getromlistbyids(roms);
-       if (rl) {
-               write_log (_T("A590/A2091 BOOT ROM '%s' %d.%d\n"), rl->path, rl->rd->ver, rl->rd->rev);
-               z = zfile_fopen(rl->path, "rb", ZFD_NORMAL);
-               if (z) {
-                       rom_size = 16384;
-                       rom = (uae_u8*)xmalloc (rom_size);
-                       zfile_fread (rom, rom_size, 1, z);
-                       rom[0x2071] = 0xe0; rom[0x2072] |= 0x40;
-                       rom[0x2075] = 0xe0; rom[0x2076] |= 0x40;
-                       rom[0x207d] = 0xe0; rom[0x207e] |= 0x40;
-                       rom[0x2081] = 0xe0; rom[0x2082] |= 0x40;
-                       rom[0x2085] = 0xe0; rom[0x2086] |= 0x40;
-                       rom[0x207b] = 0x32;
-                       p = cardmemory + 0x4000;
-                       memcpy (p, rom + 0x2000, 0x2000);
-                       memcpy (p + 0x2000, rom, 0x2000);
-               }
-               zfile_fclose(z);
-       }
-       //kickmemory[0x3592c] = 0xff;
-}
-#endif
-
 void cdtv_init (void)
 {
        close_unit ();
@@ -1775,8 +1696,9 @@ void cdtv_init (void)
        cdtv_battram_reset ();
        open_unit ();
        gui_flicker_led (LED_CD, 0, -1);
-       if (currprefs.cs_cdtvscsi)
-               init_scsi ();
+       if (currprefs.cs_cdtvscsi) {
+               init_scsi (&wd_cdtv);
+       }
 }
 
 void cdtv_check_banks (void)
index 425c887c8197e2e5dbbd39a891de4e2c35564112..df1dadb7aa6265baebd8a8f2825e44fb83130a10 100644 (file)
@@ -210,7 +210,12 @@ static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0
 static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 };
 static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
 static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
-
+static const TCHAR *hdcontrollers[] = {
+       _T("uae"),
+       _T("ide%d"),
+       _T("scsi%d"), _T("scsi%d_a2091"),  _T("scsi%d_a2091-2"), _T("scsi%d_a4091"),  _T("scsi%d_a4091-2"), _T("scsi%d_a3000"),  _T("scsi%d_a4000t"),  _T("scsi%d_cdtv"),
+       _T("scsram"), _T("scide")
+};
 static const TCHAR *obsolete[] = {
        _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
        _T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
@@ -737,11 +742,7 @@ static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TC
 static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
 {
        int i;
-       TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH];
-       TCHAR *hdcontrollers[] = { _T("uae"),
-               _T("ide0"), _T("ide1"), _T("ide2"), _T("ide3"),
-               _T("scsi0"), _T("scsi1"), _T("scsi2"), _T("scsi3"), _T("scsi4"), _T("scsi5"), _T("scsi6"),
-               _T("scsram"), _T("scide") }; /* scsram = smart card sram = pcmcia sram card */
+       TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], hdcs[MAX_DPATH];
 
        for (i = 0; i < p->mountitems; i++) {
                struct uaedev_config_data *uci = &p->mountconfig[i];
@@ -765,6 +766,8 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
                } else {
                        str1 = cfgfile_put_multipath (&p->path_hardfile, ci->rootdir);
                }
+               _stprintf(hdcs, hdcontrollers[ci->controller_type], ci->controller_unit);
+
                str1b = cfgfile_escape (str1, _T(":,"), true);
                str2b = cfgfile_escape (str2, _T(":,"), true);
                if (ci->type == UAEDEV_DIR) {
@@ -782,12 +785,12 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
                                ci->readonly ? _T("ro") : _T("rw"),
                                ci->devname ? ci->devname : _T(""), str1,
                                ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
-                               bp, ci->filesys ? ci->filesys : _T(""), hdcontrollers[ci->controller]);
+                               bp, ci->filesys ? ci->filesys : _T(""), hdcs);
                        _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"),
                                ci->readonly ? _T("ro") : _T("rw"),
                                ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b,
                                ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
-                               bp, ci->filesys ? ci->filesys : _T(""), hdcontrollers[ci->controller]);
+                               bp, ci->filesys ? ci->filesys : _T(""), hdcs);
                        if (ci->highcyl) {
                                TCHAR *s = tmp + _tcslen (tmp);
                                TCHAR *s2 = s;
@@ -946,11 +949,19 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
 
        cfgfile_write_rom (f, &p->path_rom, p->a2091romfile, _T("a2091_rom_file"));
+       if (p->a2091romfile2[0])
+               cfgfile_write_rom (f, &p->path_rom, p->a2091romfile2, _T("a2091_2_rom_file"));
        cfgfile_write_rom (f, &p->path_rom, p->a4091romfile, _T("a4091_rom_file"));
+       if (p->a4091romfile2[0])
+               cfgfile_write_rom (f, &p->path_rom, p->a4091romfile, _T("a4091_2_rom_file"));
        if (p->a2091romident[0])
                cfgfile_dwrite_str (f, _T("a2091_rom"), p->a2091romident);
+       if (p->a2091romident2[0])
+               cfgfile_dwrite_str (f, _T("a2091_2_rom"), p->a2091romident2);
        if (p->a4091romident[0])
                cfgfile_dwrite_str (f, _T("a4091_rom"), p->a4091romident);
+       if (p->a4091romident2[0])
+               cfgfile_dwrite_str (f, _T("a4091_2_rom"), p->a4091romident2);
 
        cfgfile_write_path (f, &p->path_rom, _T("flash_file"), p->flashfile);
        cfgfile_write_path (f, &p->path_rom, _T("cart_file"), p->cartfile);
@@ -1400,11 +1411,20 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool (f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug);
        cfgfile_dwrite_bool (f, _T("ics_agnus"), p->cs_dipagnus);
        cfgfile_dwrite_bool (f, _T("cia_todbug"), p->cs_ciatodbug);
+       cfgfile_dwrite_bool (f, _T("z3_autoconfig"), p->cs_z3autoconfig);
        cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
 
+       cfgfile_dwrite_bool (f, _T("z3realmapping"), p->jit_direct_compatible_memory);
+       cfgfile_dwrite_bool (f, _T("force_0x10000000_z3"), p->force_0x10000000_z3);
        cfgfile_dwrite_bool (f, _T("fastmem_autoconfig"), p->fastmem_autoconfig);
-       cfgfile_write (f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000);
-       cfgfile_dwrite (f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000);
+       if (p->fastmem_size < 0x100000 && p->fastmem_size)
+               cfgfile_write (f, _T("fastmem_size_k"), _T("%d"), p->fastmem_size / 1024);
+       else
+               cfgfile_write (f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000);
+       if (p->fastmem2_size < 0x100000 && p->fastmem2_size)
+               cfgfile_dwrite (f, _T("fastmem2_size_k"), _T("%d"), p->fastmem2_size / 1024);
+       else
+               cfgfile_dwrite (f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000);
        cfgfile_write (f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low_size / 0x100000);
        cfgfile_write (f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high_size / 0x100000);
        cfgfile_write (f, _T("z3mem_size"), _T("%d"), p->z3fastmem_size / 0x100000);
@@ -2880,27 +2900,39 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
                                return NULL;
                }
        }
-       if (ci->type == UAEDEV_CD) {
-               if (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0)
-                       return NULL;
-       }
-       if (ci->type == UAEDEV_TAPE) {
-               if (ci->controller != HD_CONTROLLER_UAE && (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0))
-                       return NULL;
+       for (;;) {
+               if (ci->type == UAEDEV_CD) {
+                       if (ci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST)
+                               break;
+                       if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
+                               break;
+               } else if (ci->type == UAEDEV_TAPE) {
+                       if (ci->controller_type == HD_CONTROLLER_TYPE_UAE)
+                               break;
+                       if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
+                               break;
+               } else {
+                       break;
+               }
+               return NULL;
        }
+
        if (index < 0) {
-               if (ci->controller != HD_CONTROLLER_UAE) {
-                       int ctrl = ci->controller;
+               if (ci->controller_type != HD_CONTROLLER_TYPE_UAE) {
+                       int ctrl = ci->controller_type;
+                       int cunit = ci->controller_unit;
                        for (;;) {
                                for (i = 0; i < p->mountitems; i++) {
-                                       if (p->mountconfig[i].ci.controller == ctrl) {
-                                               ctrl++;
-                                               if (ctrl == HD_CONTROLLER_IDE3 + 1 || ctrl == HD_CONTROLLER_SCSI6 + 1)
+                                       if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_unit == cunit) {
+                                               cunit++;
+                                               if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4)
+                                                       return NULL;
+                                               if (ctrl >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctrl <= HD_CONTROLLER_TYPE_SCSI_LAST && cunit == 7)
                                                        return NULL;
                                        }
                                }
                                if (i == p->mountitems) {
-                                       ci->controller = ctrl;
+                                       ci->controller_unit = cunit;
                                        break;
                                }
                        }
@@ -2967,24 +2999,46 @@ static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num)
        p->custom_memory_sizes[num] = size;
 }
 
-static int get_filesys_controller (const TCHAR *hdc)
+static void get_filesys_controller (const TCHAR *hdc, int *type, int *num)
 {
-       int hdcv = HD_CONTROLLER_UAE;
+       int hdcv = HD_CONTROLLER_TYPE_UAE;
+       int hdunit = 0;
        if(_tcslen (hdc) >= 4 && !_tcsncmp (hdc, _T("ide"), 3)) {
-               hdcv = hdc[3] - '0' + HD_CONTROLLER_IDE0;
-               if (hdcv < HD_CONTROLLER_IDE0 || hdcv > HD_CONTROLLER_IDE3)
-                       hdcv = 0;
-       }
-       if(_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scsi"), 4)) {
-               hdcv = hdc[4] - '0' + HD_CONTROLLER_SCSI0;
-               if (hdcv < HD_CONTROLLER_SCSI0 || hdcv > HD_CONTROLLER_SCSI6)
-                       hdcv = 0;
-       }
-       if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, _T("scsram"), 6))
-               hdcv = HD_CONTROLLER_PCMCIA_SRAM;
-       if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6))
-               hdcv = HD_CONTROLLER_PCMCIA_IDE;
-       return hdcv;
+               hdcv = HD_CONTROLLER_TYPE_IDE_AUTO;
+               hdunit = hdc[3] - '0';
+               if (hdunit < 0 || hdunit > 3)
+                       hdunit = 0;
+       } else if(_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scsi"), 4)) {
+               const TCHAR *ext;
+               hdcv = HD_CONTROLLER_TYPE_SCSI_AUTO;
+               hdunit = hdc[4] - '0';
+               if (hdunit < 0 || hdunit > 7)
+                       hdunit = 0;
+               ext = _tcsrchr (hdc, '_');
+               if (ext) {
+                       ext++;
+                       if (!_tcsicmp(ext, _T("a2091")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A2091;
+                       if (!_tcsicmp(ext, _T("a2091-2")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A2091_2;
+                       if (!_tcsicmp(ext, _T("a3000")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A3000;
+                       if (!_tcsicmp(ext, _T("a4091")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A4091;
+                       if (!_tcsicmp(ext, _T("a4091-2")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A4091_2;
+                       if (!_tcsicmp(ext, _T("a4000t")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_A4000T;
+                       if (!_tcsicmp(ext, _T("cdtv")))
+                               hdcv = HD_CONTROLLER_TYPE_SCSI_CDTV;
+               }
+       } else if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, _T("scsram"), 6)) {
+               hdcv = HD_CONTROLLER_TYPE_PCMCIA_SRAM;
+       } else if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6)) {
+               hdcv = HD_CONTROLLER_TYPE_PCMCIA_IDE;
+       }
+       *type = hdcv;
+       *num = hdunit;
 }
 
 static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty)
@@ -3076,7 +3130,7 @@ static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struc
                if (!_tcsicmp (key, _T("unit")))
                        uci->unit = v;
                if (!_tcsicmp (key, _T("controller")))
-                       uci->controller = get_filesys_controller (val);
+                       get_filesys_controller (val, &uci->controller_type, &uci->controller_unit);
                if (!_tcsicmp (key, _T("flags")))
                        uci->flags = v;
                if (!_tcsicmp (key, _T("priority")))
@@ -3237,7 +3291,7 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA
                                TCHAR *tmpp2 = _tcschr (tmpp, ',');
                                if (tmpp2)
                                        *tmpp2++ = 0;
-                               uci.controller = get_filesys_controller (tmpp);
+                               get_filesys_controller (tmpp, &uci.controller_type, &uci.controller_unit);
                                if (tmpp2) {
                                        if (getintval2 (&tmpp2, &uci.highcyl, ',')) {
                                                getintval (&tmpp2, &uci.pcyls, '/');
@@ -3341,7 +3395,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA
                                } else if (!_tcscmp (s, _T("filesys"))) {
                                        _tcscpy (uci->filesys, value);
                                } else if (!_tcscmp (s, _T("controller"))) {
-                                       uci->controller = get_filesys_controller (value);
+                                       get_filesys_controller (value, &uci->controller_type, &uci->controller_unit);
                                }
                        }
                }
@@ -3476,8 +3530,11 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno (option, value, _T("cia_todbug"), &p->cs_ciatodbug)
                || cfgfile_yesno (option, value, _T("denise_noehb"), &p->cs_denisenoehb)
                || cfgfile_yesno (option, value, _T("ics_agnus"), &p->cs_dipagnus)
+               || cfgfile_yesno (option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig)
                || cfgfile_yesno (option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
                || cfgfile_yesno (option, value, _T("fastmem_autoconfig"), &p->fastmem_autoconfig)
+               || cfgfile_yesno (option, value, _T("z3realmapping"), &p->jit_direct_compatible_memory)
+               || cfgfile_yesno (option, value, _T("force_0x10000000_z3"), &p->force_0x10000000_z3)
                || cfgfile_yesno (option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
                || cfgfile_yesno (option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
                || cfgfile_yesno (option, value, _T("synchronize_clock"), &p->tod_hack)
@@ -3519,7 +3576,9 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_intval (option, value, _T("ramsey"), &p->cs_ramseyrev, 1)
                || cfgfile_doubleval (option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate)
                || cfgfile_intval (option, value, _T("fastmem_size"), &p->fastmem_size, 0x100000)
+               || cfgfile_intval (option, value, _T("fastmem_size_k"), &p->fastmem_size, 1024)
                || cfgfile_intval (option, value, _T("fastmem2_size"), &p->fastmem2_size, 0x100000)
+               || cfgfile_intval (option, value, _T("fastmem2_size_k"), &p->fastmem2_size, 1024)
                || cfgfile_intval (option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000)
                || cfgfile_intval (option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000)
                || cfgfile_intval (option, value, _T("z3mem_size"), &p->z3fastmem_size, 0x100000)
@@ -3567,11 +3626,15 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_path (option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR), &p->path_rom)
                || cfgfile_path (option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR), &p->path_rom)
                || cfgfile_path (option, value, _T("a2091_rom_file"), p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR), &p->path_rom)
+               || cfgfile_path (option, value, _T("a2091_2_rom_file"), p->a2091romfile2, sizeof p->a2091romfile2 / sizeof (TCHAR), &p->path_rom)
                || cfgfile_path (option, value, _T("a4091_rom_file"), p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR), &p->path_rom)
+               || cfgfile_path (option, value, _T("a4091_2_rom_file"), p->a4091romfile2, sizeof p->a4091romfile2 / sizeof (TCHAR), &p->path_rom)
                || cfgfile_rom (option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof (TCHAR))
                || cfgfile_rom (option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR))
                || cfgfile_rom (option, value, _T("a2091_rom_file_id"), p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR))
+               || cfgfile_rom (option, value, _T("a2091_2_rom_file_id"), p->a2091romfile2, sizeof p->a2091romfile2 / sizeof (TCHAR))
                || cfgfile_rom (option, value, _T("a4091_rom_file_id"), p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR))
+               || cfgfile_rom (option, value, _T("a4091_2_rom_file_id"), p->a4091romfile2, sizeof p->a4091romfile2 / sizeof (TCHAR))
                || cfgfile_path (option, value, _T("amax_rom_file"), p->amaxromfile, sizeof p->amaxromfile / sizeof (TCHAR))
                || cfgfile_path (option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof (TCHAR), &p->path_rom)
                || cfgfile_path (option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof (TCHAR), &p->path_rom)
@@ -3606,10 +3669,18 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                decode_rom_ident (p->a2091romident, sizeof p->a2091romident / sizeof (TCHAR), p->a2091romident, ROMTYPE_A2091BOOT);
                return 1;
        }
+       if (cfgfile_string (option, value, _T("a2091_2_rom"), p->a2091romident2, sizeof p->a2091romident2 / sizeof (TCHAR))) {
+               decode_rom_ident (p->a2091romident2, sizeof p->a2091romident2 / sizeof (TCHAR), p->a2091romident2, ROMTYPE_A2091BOOT);
+               return 1;
+       }
        if (cfgfile_string (option, value, _T("a4091_rom"), p->a4091romident, sizeof p->a4091romident / sizeof (TCHAR))) {
                decode_rom_ident (p->a4091romident, sizeof p->a4091romident / sizeof (TCHAR), p->a4091romident, ROMTYPE_A4091BOOT);
                return 1;
        }
+       if (cfgfile_string (option, value, _T("a4091_2_rom"), p->a4091romident2, sizeof p->a4091romident2 / sizeof (TCHAR))) {
+               decode_rom_ident (p->a4091romident2, sizeof p->a4091romident2 / sizeof (TCHAR), p->a4091romident2, ROMTYPE_A4091BOOT);
+               return 1;
+       }
        if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
                decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
                return 1;
@@ -4171,7 +4242,9 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real
        subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR));
        subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR));
        subst (p->path_rom.path[0], p->a2091romfile, sizeof p->a2091romfile / sizeof (TCHAR));
+       subst (p->path_rom.path[0], p->a2091romfile2, sizeof p->a2091romfile2 / sizeof (TCHAR));
        subst (p->path_rom.path[0], p->a4091romfile, sizeof p->a4091romfile / sizeof (TCHAR));
+       subst (p->path_rom.path[0], p->a4091romfile2, sizeof p->a4091romfile2 / sizeof (TCHAR));
 
        return 1;
 }
@@ -5114,6 +5187,7 @@ void default_prefs (struct uae_prefs *p, int type)
        p->uae_hide = 0;
        p->uae_hide_autoconfig = false;
        p->jit_direct_compatible_memory = true;
+       p->force_0x10000000_z3 = false;
 
        p->mountitems = 0;
        for (i = 0; i < MOUNT_CONFIG_SIZE; i++) {
@@ -5503,7 +5577,9 @@ static void buildin_default_prefs (struct uae_prefs *p)
        _tcscpy (p->romfile, _T(""));
        _tcscpy (p->romextfile, _T(""));
        _tcscpy (p->a2091romfile, _T(""));
+       _tcscpy (p->a2091romfile2, _T(""));
        _tcscpy (p->a4091romfile, _T(""));
+       _tcscpy (p->a4091romfile2, _T(""));
        _tcscpy (p->flashfile, _T(""));
        _tcscpy (p->cartfile, _T(""));
        _tcscpy (p->rtcfile, _T(""));
@@ -6041,6 +6117,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
        p->cs_resetwarning = 1;
        p->cs_slowmemisfast = 0;
        p->cs_ciatodbug = false;
+       p->cs_z3autoconfig = false;
 
        switch (p->cs_compatible)
        {
@@ -6113,6 +6190,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_mbdmac = 1;
                p->cs_ksmirror_e0 = 0;
                p->cs_ciaatod = p->ntscmode ? 2 : 1;
+               p->cs_z3autoconfig = true;
                break;
        case CP_A3000T: // A3000T
                p->cs_rtc = 2;
@@ -6121,6 +6199,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_mbdmac = 1;
                p->cs_ksmirror_e0 = 0;
                p->cs_ciaatod = p->ntscmode ? 2 : 1;
+               p->cs_z3autoconfig = true;
                break;
        case CP_A4000: // A4000
                p->cs_rtc = 2;
@@ -6131,6 +6210,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_ksmirror_a8 = 0;
                p->cs_ksmirror_e0 = 0;
                p->cs_ciaoverlay = 0;
+               p->cs_z3autoconfig = true;
                break;
        case CP_A4000T: // A4000T
                p->cs_rtc = 2;
@@ -6141,6 +6221,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_ksmirror_a8 = 0;
                p->cs_ksmirror_e0 = 0;
                p->cs_ciaoverlay = 0;
+               p->cs_z3autoconfig = true;
                break;
        }
        return 1;
index b7b69079234c4c3bcc688c245f6101a34dc4eec0..c120b5a18d0f3809c9f4804c2f9c0ca3b1d99fa1 100644 (file)
@@ -22,8 +22,8 @@
  * - If possible, test mmu030_table_search with all kinds of translations
  *   (early termination, invalid descriptors, bus errors, indirect
  *   descriptors, PTEST in different levels, etc).
- * - Check which bits of an ATC entry should be set and which should be
- *   un-set, if an invalid translation occurs.
+ * - Check which bits of an ATC entry or the status register should be set 
+ *   and which should be un-set, if an invalid translation occurs.
  * - Handle cache inhibit bit when accessing ATC entries
  */
 
@@ -1018,7 +1018,7 @@ void mmu030_decode_rp(uae_u64 RP) {
  * reserved (must be 1111 110)
  *
  * -xxx xxxx xxxx xxxx ---- ---- ---- ---- | ---- ---- ---- ---- ---- ---- ---- ----
- * limit (only used with early termination page decriptor)
+ * limit (only used with early termination page descriptor)
  *
  * x--- ---- ---- ---- ---- ---- ---- ---- | ---- ---- ---- ---- ---- ---- ---- ----
  * 0 = upper limit, 1 = lower limit (only used with early termination page descriptor)
@@ -1058,7 +1058,8 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
         uae_u32 limit = 0;
         uae_u32 unused_fields_mask = 0;
         bool super = (fc&4) ? true : false;
-        bool write_protect = false;
+        bool super_violation = false;
+        bool write_protected = false;
         bool cache_inhibit = false;
         bool descr_modified = false;
         
@@ -1175,21 +1176,24 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
         /* Upper level tables */
         do {
             if (descr_num) { /* if not root pointer */
+                /* Check protection */
+                if ((descr_size==8) && (descr[0]&DESCR_S) && !super) {
+                    super_violation = true;
+                }
+                if (descr[0]&DESCR_WP) {
+                    write_protected = true;
+                }
+                
                 /* Set the updated bit */
-                if (!level && !(descr[0]&DESCR_U) && !(mmu030.status&MMUSR_SUPER_VIOLATION)) {
+                if (!level && !(descr[0]&DESCR_U) && !super_violation) {
                     descr[0] |= DESCR_U;
                     phys_put_long(descr_addr[descr_num], descr[0]);
                 }
-                /* Update status bits */
-                if (descr_size==8) {
-                    if (descr[0]&DESCR_S)
-                        mmu030.status |= super ? 0 : MMUSR_SUPER_VIOLATION;
-                }
-                if (descr[0]&DESCR_WP) {
-                    mmu030.status |= (descr[0]&DESCR_WP) ? MMUSR_WRITE_PROTECTED : 0;
-                    write_protect = true;
-                }
                 
+                /* Update status bits */
+                mmu030.status |= super_violation ? MMUSR_SUPER_VIOLATION : 0;
+                mmu030.status |= write_protected ? MMUSR_WRITE_PROTECTED : 0;                
+
                 /* Check if ptest level is reached */
                 if (level && (level==descr_num)) {
                     goto stop_search;
@@ -1209,12 +1213,16 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
                 limit = (descr[0]&DESCR_LIMIT_MASK)>>16;
                 if ((descr[0]&DESCR_LOWER_MASK) && (table_index<limit)) {
                     mmu030.status |= (MMUSR_LIMIT_VIOLATION|MMUSR_INVALID);
+#if MMU030_REG_DBG_MSG
                     write_log(_T("limit violation (lower limit %i)\n"),limit);
+#endif
                     goto stop_search;
                 }
                 if (!(descr[0]&DESCR_LOWER_MASK) && (table_index>limit)) {
                     mmu030.status |= (MMUSR_LIMIT_VIOLATION|MMUSR_INVALID);
+#if MMU030_REG_DBG_MSG
                     write_log(_T("limit violation (upper limit %i)\n"),limit);
+#endif
                     goto stop_search;
                 }
             }
@@ -1309,9 +1317,17 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
     handle_page_descriptor:
         
         if (descr_num) { /* if not root pointer */
-            if (!level && !(mmu030.status&MMUSR_SUPER_VIOLATION)) {
+            /* check protection */
+            if ((descr_size==8) && (descr[0]&DESCR_S) && !super) {
+                super_violation = true;
+            }
+            if (descr[0]&DESCR_WP) {
+                write_protected = true;
+            }
+
+            if (!level && !super_violation) {
                 /* set modified bit */
-                if (!(descr[0]&DESCR_M) && write && !(mmu030.status&MMUSR_WRITE_PROTECTED)) {
+                if (!(descr[0]&DESCR_M) && write && !write_protected) {
                     descr[0] |= DESCR_M;
                     descr_modified = true;
                 }
@@ -1326,19 +1342,14 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
                 }
             }
             
-            if ((descr_size==8) && (descr[0]&DESCR_S)) {
-                mmu030.status |= super ? 0 : MMUSR_SUPER_VIOLATION;
-            }
-            
+            /* update status bits */
+            mmu030.status |= super_violation ? MMUSR_SUPER_VIOLATION : 0;
+            mmu030.status |= write_protected ? MMUSR_WRITE_PROTECTED : 0;
+
             /* check if caching is inhibited */
             cache_inhibit = descr[0]&DESCR_CI ? true : false;
             
-            /* check write protection */
-            if (descr[0]&DESCR_WP) {
-                mmu030.status |= (descr[0]&DESCR_WP) ? MMUSR_WRITE_PROTECTED : 0;
-                write_protect = true;
-            }
-            /* TODO: check if this is handled at correct point (maybe before updating descr?) */
+            /* check for the modified bit and set it in the status register */
             mmu030.status |= (descr[0]&DESCR_M) ? MMUSR_MODIFIED : 0;
         }
         
@@ -1353,12 +1364,16 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
                     limit = (descr[0]&DESCR_LIMIT_MASK)>>16;
                     if ((descr[0]&DESCR_LOWER_MASK) && (table_index<limit)) {
                         mmu030.status |= (MMUSR_LIMIT_VIOLATION|MMUSR_INVALID);
+#if MMU030_REG_DBG_MSG
                         write_log(_T("Limit violation (lower limit %i)\n"),limit);
+#endif
                         goto stop_search;
                     }
                     if (!(descr[0]&DESCR_LOWER_MASK) && (table_index>limit)) {
                         mmu030.status |= (MMUSR_LIMIT_VIOLATION|MMUSR_INVALID);
+#if MMU030_REG_DBG_MSG
                         write_log(_T("Limit violation (upper limit %i)\n"),limit);
+#endif
                         goto stop_search;
                     }
                 }
@@ -1399,10 +1414,7 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
     
     /* check if we have to handle ptest */
     if (level) {
-        if (mmu030.status&MMUSR_INVALID) {
-            /* these bits are undefined, if the I bit is set: */
-            mmu030.status &= ~(MMUSR_WRITE_PROTECTED|MMUSR_MODIFIED|MMUSR_SUPER_VIOLATION);
-        }
+        /* Note: wp, m and sv bits are undefined if the invalid bit is set */
         mmu030.status = (mmu030.status&~MMUSR_NUM_LEVELS_MASK) | descr_num;
 
         /* If root pointer is page descriptor (descr_num 0), return 0 */
@@ -1445,13 +1457,9 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
     } else {
         mmu030.atc[i].physical.bus_error = false;
     }
-    if (write && !(mmu030.status&MMUSR_SUPER_VIOLATION) && !(mmu030.status&MMUSR_LIMIT_VIOLATION)) {
-        mmu030.atc[i].physical.modified = true;
-    } else {
-        mmu030.atc[i].physical.modified = false;
-    }
     mmu030.atc[i].physical.cache_inhibit = cache_inhibit;
-    mmu030.atc[i].physical.write_protect = write_protect;
+    mmu030.atc[i].physical.modified = (mmu030.status&MMUSR_MODIFIED) ? true : false;
+    mmu030.atc[i].physical.write_protect = (mmu030.status&MMUSR_WRITE_PROTECTED) ? true : false;
 
 #if MMU030_ATC_DBG_MSG    
     write_log(_T("ATC create entry(%i): logical = %08X, physical = %08X, FC = %i\n"), i,
@@ -1491,11 +1499,9 @@ void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write) {
     }
     
     mmu030.status |= mmu030.atc[i].physical.bus_error ? (MMUSR_BUS_ERROR|MMUSR_INVALID) : 0;
+    /* Note: write protect and modified bits are undefined if the invalid bit is set */
     mmu030.status |= mmu030.atc[i].physical.write_protect ? MMUSR_WRITE_PROTECTED : 0;
     mmu030.status |= mmu030.atc[i].physical.modified ? MMUSR_MODIFIED : 0;
-    if (mmu030.status&MMUSR_INVALID) {
-        mmu030.status &= ~(MMUSR_WRITE_PROTECTED|MMUSR_MODIFIED);
-    }
 }
 
 /* This function is used for PTEST level 1 - 7. */
@@ -1745,10 +1751,8 @@ uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int size, int fl
  * stored in the ATC entries. If a matching entry is found it sets
  * the history bit and returns the cache index of the entry. */
 int mmu030_logical_is_in_atc(uaecptr addr, uae_u32 fc, bool write) {
-    uaecptr physical_addr = 0;
     uaecptr logical_addr = 0;
     uae_u32 addr_mask = mmu030.translation.page.imask;
-    uae_u32 page_index = addr & mmu030.translation.page.mask;
        uae_u32 maddr = addr & addr_mask;
     int offset = (maddr >> mmu030.translation.page.size) & 0x1f;
 
@@ -1760,10 +1764,12 @@ int mmu030_logical_is_in_atc(uaecptr addr, uae_u32 fc, bool write) {
         if (maddr==(logical_addr&addr_mask) &&
             (mmu030.atc[index].logical.fc==fc) &&
             mmu030.atc[index].logical.valid) {
-            /* If M bit is set or access is read, return true
-             * else invalidate entry */
-                               if (mmu030.atc[index].physical.modified || !write) {
-                                       /* Maintain history bit */
+            /* If access is valid write and M bit is not set, invalidate entry
+             * else return index */
+            if (!write || mmu030.atc[index].physical.modified ||
+                mmu030.atc[index].physical.write_protect ||
+                mmu030.atc[index].physical.bus_error) {
+                /* Maintain history bit */
                                        mmu030_atc_handle_history_bit(index);
                                        atcindextable[offset] = index;
                                        return index;
index 2260ff29cd0bffd6d9b16dec3d8ab7d127841e3e..7456672551b458480c4e579b4a5a399b8fa6c278 100644 (file)
@@ -5,7 +5,7 @@
 *
 * Copyright 1995-2002 Bernd Schmidt
 * Copyright 1995 Alessandro Bissacco
-* Copyright 2000-2010 Toni Wilen
+* Copyright 2000-2014 Toni Wilen
 */
 
 #include "sysconfig.h"
@@ -50,6 +50,7 @@
 #endif
 #include "gayle.h"
 #include "gfxfilter.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "a2065.h"
 #include "gfxboard.h"
@@ -148,7 +149,6 @@ static bool bplcon0_interlace_seen;
 static int scandoubled_line;
 static bool vsync_rendered, frame_rendered, frame_shown;
 static int vsynctimeperline;
-static int jitcount = 0;
 static int frameskiptime;
 static bool genlockhtoggle;
 static bool genlockvtoggle;
@@ -198,6 +198,7 @@ int maxvpos_display = MAXVPOS_PAL; // value used for display size
 int hsyncendpos, hsyncstartpos;
 static int maxvpos_total = 511;
 int minfirstline = VBLANK_ENDLINE_PAL;
+int firstblankedline;
 static int equ_vblank_endline = EQU_ENDLINE_PAL;
 static bool equ_vblank_toggle = true;
 double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored, vblank_hz_nom;
@@ -451,7 +452,6 @@ uae_u32 get_copper_address (int copno)
 
 void reset_frame_rate_hack (void)
 {
-       jitcount = 0;
        if (currprefs.m68k_speed >= 0)
                return;
 
@@ -621,7 +621,7 @@ STATIC_INLINE int get_equ_vblank_endline (void)
        return equ_vblank_endline + (equ_vblank_toggle ? (lof_current ? 1 : 0) : 0);
 }
 
-#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (bplcon0 & 0x40))
+#define HARD_DDF_LIMITS_DISABLED ((beamcon0 & 0x80) || (beamcon0 & 0x4000) || (bplcon0 & 0x40))
 /* The HRM says 0xD8, but that can't work... */
 #define HARD_DDF_STOP (HARD_DDF_LIMITS_DISABLED ? 0xff : 0xd6)
 #define HARD_DDF_START_REAL 0x18
@@ -2540,20 +2540,6 @@ static void start_bpl_dma (int hpos, int hstart)
        estimate_last_fetch_cycle (hstart);
 
        last_fetch_hpos = hstart;
-
-
-#if 0
-       /* If someone already wrote BPL1DAT, clear the area between that point and
-       the real fetch start.  */
-       if (!nodraw ()) {
-               if (thisline_decision.plfleft >= 0) {
-                       out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res);
-                       out_offs = out_nbits >> 5;
-                       out_nbits &= 31;
-               }
-               update_toscr_planes ();
-       }
-#endif
 }
 
 #if 0
@@ -3744,7 +3730,7 @@ void compute_framesync (void)
                gfxvidinfo.drawbuffer.extrawidth = 0;
                gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
 
-               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline + 1) << vres2;
+               gfxvidinfo.drawbuffer.inheight = ((firstblankedline < maxvpos ? firstblankedline : maxvpos) - minfirstline + 1) << vres2;
                gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
 
        } else {
@@ -3877,12 +3863,14 @@ void init_hz (bool fullinit)
                vpos_count = maxvpos;
                vpos_count_diff = maxvpos;
        }
+       firstblankedline = maxvpos + 1;
 
        if (beamcon0 & 0x80) {
                // programmable scanrates (ECS Agnus)
                if (vtotal >= MAXVPOS)
                        vtotal = MAXVPOS - 1;
                maxvpos = vtotal + 1;
+               firstblankedline = maxvpos + 1;
                if (htotal >= MAXHPOS)
                        htotal = MAXHPOS - 1;
                maxhpos = htotal + 1;
@@ -3890,13 +3878,31 @@ void init_hz (bool fullinit)
                vblank_hz_shf = vblank_hz;
                vblank_hz_lof = 227.0 * 313.0 * 50.0 / (maxvpos * maxhpos);;
                vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);;
-               minfirstline = vsstop > vbstop ? vsstop : vbstop;
-               if (minfirstline > maxvpos / 2) 
-                       minfirstline = vsstop > vbstop ? vbstop : vsstop;
+
+               if ((beamcon0 & 0x1000) && (beamcon0 & 0x0200)) { // VARVBEN + VARVSYEN
+                       minfirstline = vsstop > vbstop ? vsstop : vbstop;
+                       if (minfirstline > maxvpos / 2) 
+                               minfirstline = vsstop > vbstop ? vbstop : vsstop;
+                       firstblankedline = vbstrt;
+               } else if (beamcon0 & 0x0200) {
+                       minfirstline = vsstop;
+                       if (minfirstline > maxvpos / 2) 
+                               minfirstline = 0;
+               } else if (beamcon0 & 0x1000) {
+                       minfirstline = vbstop;
+                       if (minfirstline > maxvpos / 2) 
+                               minfirstline = 0;
+                       firstblankedline = vbstrt;
+               }
+               
                if (minfirstline < 2)
                        minfirstline = 2;
                if (minfirstline >= maxvpos)
                        minfirstline = maxvpos - 1;
+
+               if (firstblankedline < minfirstline)
+                       firstblankedline = maxvpos + 1;
+
                sprite_vblank_endline = minfirstline - 2;
                maxvpos_nom = maxvpos;
                maxvpos_display = maxvpos;
@@ -3926,15 +3932,35 @@ void init_hz (bool fullinit)
                vblank_hz = 300;
        maxhpos_short = maxhpos;
        set_delay_lastcycle ();
-       if (beamcon0 & 0x80) {
-               if (hbstrt > maxhpos)
-                       hsyncstartpos = hbstrt;
-               else
-                       hsyncstartpos = maxhpos + hbstrt;
-               if (hbstop > maxhpos)
-                       hsyncendpos = maxhpos - hbstop - 2;
-               else
-                       hsyncendpos = hbstop - 2;
+       if ((beamcon0 & 0x80) && (beamcon0 & 0x0100)) {
+
+               hsyncstartpos = hsstrt;
+               hsyncendpos = hsstop;
+
+               if ((bplcon0 & 1) && (bplcon3 & 1)) {
+
+                       if (hbstrt > maxhpos / 2) {
+                               if (hsyncstartpos < hbstrt)
+                                       hsyncstartpos = hbstrt;
+                       } else {
+                               if (hsyncstartpos > hbstrt)
+                                       hsyncstartpos = hbstrt;
+                       }
+
+                       if (hbstop > maxhpos / 2) {
+                               if (hsyncendpos > hbstop)
+                                       hsyncendpos = hbstop;
+                       } else {
+                               if (hsyncendpos < hbstop)
+                                       hsyncendpos = hbstop;
+                       }
+               }
+
+               if (hsyncstartpos < hsyncendpos)
+                       hsyncstartpos = maxhpos + hsyncstartpos;
+
+               hsyncendpos--;
+
                if (hsyncendpos < 2)
                        hsyncendpos = 2;
        } else {
@@ -4730,6 +4756,7 @@ static void BEAMCON0 (uae_u16 v)
                        if (v & ~0x20)
                                write_log (_T("warning: %04X written to BEAMCON0 PC=%08X\n"), v, M68K_GETPC);
                }
+               calcdiw();
        }
 }
 
@@ -4840,14 +4867,6 @@ static void BPLCON0_Denise (int hpos, uae_u16 v, bool immediate)
        // fake unused 0x0080 bit as an EHB bit (see below)
        if (isehb (bplcon0d, bplcon2))
                v |= 0x80;
-#if 0
-       if (hpos >= 0x18 && is_bitplane_dma (hpos - 2) == 1) {
-               for (int i = 0; i < MAX_PLANES; i++) {
-                       if (i >= GET_PLANES (bplcon0))
-                               todisplay[i][0] = 0;
-               }
-       }
-#endif
        if (immediate) {
                record_register_change (hpos, 0x100, v);
        } else {
@@ -5001,7 +5020,7 @@ static void BPL2MOD (int hpos, uae_u16 v)
  */
 static void BPLxDAT (int hpos, int num, uae_u16 v)
 {
-       // only BPL0DAT access can do anything visible
+       // only BPL1DAT access can do anything visible
        if (num == 0 && hpos >= 8) {
                decide_line (hpos);
                decide_fetch_safe (hpos);
@@ -8591,7 +8610,7 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n
        case 0x1C0: if (htotal != value) { htotal = value & (MAXHPOS_ROWS - 1); varsync (); } break;
        case 0x1C2: if (hsstop != value) { hsstop = value & (MAXHPOS_ROWS - 1); varsync (); } break;
        case 0x1C4: if (hbstrt != value) { hbstrt = value & (MAXHPOS_ROWS - 1); varsync (); } break;
-       case 0x1C6: if (hbstop != value) { hbstop = value & (MAXHPOS_ROWS - 1); varsync (); } break;
+       case 0x1C6:     if (hbstop != value) { hbstop = value & (MAXHPOS_ROWS - 1); varsync ();} break;
        case 0x1C8: if (vtotal != value) { vtotal = value & (MAXVPOS_LINES_ECS - 1); varsync (); } break;
        case 0x1CA: if (vsstop != value) { vsstop = value & (MAXVPOS_LINES_ECS - 1); varsync (); } break;
        case 0x1CC: if (vbstrt < value || vbstrt > (value & (MAXVPOS_LINES_ECS - 1)) + 1) { vbstrt = value & (MAXVPOS_LINES_ECS - 1); varsync (); } break;
@@ -9154,6 +9173,7 @@ uae_u8 *restore_custom_extra (uae_u8 *src)
        currprefs.cs_ksmirror_a8 = changed_prefs.cs_ksmirror_a8 = RBB;
        currprefs.cs_ksmirror_e0 = changed_prefs.cs_ksmirror_e0 = RBB;
        currprefs.cs_resetwarning = changed_prefs.cs_resetwarning = RBB;
+       currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig = RBB;
 
        return src;
 }
@@ -9205,6 +9225,7 @@ uae_u8 *save_custom_extra (int *len, uae_u8 *dstptr)
        SB (currprefs.cs_ksmirror_a8 ? 1 : 0);
        SB (currprefs.cs_ksmirror_e0 ? 1 : 0);
        SB (currprefs.cs_resetwarning ? 1 : 0);
+       SB (currprefs.cs_z3autoconfig ? 1 : 0);
 
        *len = dst - dstbak;
        return dstbak;
@@ -9319,6 +9340,7 @@ void check_prefs_changed_custom (void)
        currprefs.cs_slowmemisfast = changed_prefs.cs_slowmemisfast;
        currprefs.cs_dipagnus = changed_prefs.cs_dipagnus;
        currprefs.cs_denisenoehb = changed_prefs.cs_denisenoehb;
+       currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig;
 
        if (currprefs.chipset_mask != changed_prefs.chipset_mask ||
                currprefs.picasso96_nocustom != changed_prefs.picasso96_nocustom ||
index 7122210998df45c52ba7f72941a6dd9bb8c7d285..9e91c9e99b1cf60f62512636d137cb7229ee5cd4 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -3093,10 +3093,36 @@ static void show_exec_lists (TCHAR *t)
                                TCHAR *name = getfrombstr (get_long_debug (doslist + 40));
                                console_out_f (_T("%08x: %d %08x '%s'\n"), doslist, type, msgport, name);
                                if (type == 0) {
+                                       uaecptr fssm = get_long_debug(doslist + 28) << 2;
                                        console_out_f (_T(" - H=%08x Stack=%5d Pri=%2d Start=%08x Seg=%08x GV=%08x\n"),
                                                get_long_debug (doslist + 16) << 2, get_long_debug (doslist + 20),
-                                               get_long_debug (doslist + 24), get_long_debug (doslist + 28),
+                                               get_long_debug (doslist + 24), fssm,
                                                get_long_debug (doslist + 32) << 2, get_long_debug (doslist + 36));
+                                       if (fssm >= 0x100 && (fssm & 3) == 0) {
+                                               TCHAR *unitname = getfrombstr(get_long_debug(fssm + 4));
+                                               console_out_f (_T("   %s:%d %08x\n"), unitname, get_long_debug(fssm), get_long_debug(fssm + 8));
+                                               uaecptr de = get_long_debug(fssm + 8) << 2;
+                                               if (de) {
+                                                       console_out_f (_T("    TableSize       %u\n"), get_long_debug(de + 0));
+                                                       console_out_f (_T("    SizeBlock       %u\n"), get_long_debug(de + 4));
+                                                       console_out_f (_T("    SecOrg          %u\n"), get_long_debug(de + 8));
+                                                       console_out_f (_T("    Surfaces        %u\n"), get_long_debug(de + 12));
+                                                       console_out_f (_T("    SectorPerBlock  %u\n"), get_long_debug(de + 16));
+                                                       console_out_f (_T("    BlocksPerTrack  %u\n"), get_long_debug(de + 20));
+                                                       console_out_f (_T("    Reserved        %u\n"), get_long_debug(de + 24));
+                                                       console_out_f (_T("    PreAlloc        %u\n"), get_long_debug(de + 28));
+                                                       console_out_f (_T("    Interleave      %u\n"), get_long_debug(de + 32));
+                                                       console_out_f (_T("    LowCyl          %u\n"), get_long_debug(de + 36));
+                                                       console_out_f (_T("    HighCyl         %u (Total %u)\n"), get_long_debug(de + 40), get_long_debug(de + 40) - get_long_debug(de + 36) + 1);
+                                                       console_out_f (_T("    NumBuffers      %u\n"), get_long_debug(de + 44));
+                                                       console_out_f (_T("    BufMemType      0x%08x\n"), get_long_debug(de + 48));
+                                                       console_out_f (_T("    MaxTransfer     0x%08x\n"), get_long_debug(de + 52));
+                                                       console_out_f (_T("    Mask            0x%08x\n"), get_long_debug(de + 56));
+                                                       console_out_f (_T("    BootPri         %d\n"), get_long_debug(de + 60));
+                                                       console_out_f (_T("    DosType         0x%08x\n"), get_long_debug(de + 64));
+                                               }
+                                               xfree(unitname);
+                                       }
                                }
                                xfree (name);
                                doslist = get_long_debug (doslist) << 2;
@@ -3163,8 +3189,8 @@ static void show_exec_lists (TCHAR *t)
                        if (!resident)
                                break;
                        if (resident & 0x80000000) {
-                               write_log (_T("-> %08X\n"), resident & ~0x7fffffff);
-                               list = resident & ~0x7fffffff;
+                               console_out_f (_T("-> %08X\n"), resident & 0x7fffffff);
+                               list = resident & 0x7fffffff;
                                continue;
                        }
                        uae_u8 *addr;
index f9cf51b60e0c5a75261fdb4d8d6c6798091a206e..596417db45e6296c5220f1ec98c141cde1a90849 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -215,7 +215,7 @@ typedef struct {
 
 static uae_u16 bigmfmbufw[0x4000 * DDHDMULT];
 static drive floppy[MAX_FLOPPY_DRIVES];
-static TCHAR dfxhistory[2][MAX_PREVIOUS_FLOPPIES][MAX_DPATH];
+static TCHAR dfxhistory[HISTORY_MAX][MAX_PREVIOUS_IMAGES][MAX_DPATH];
 
 static uae_u8 exeheader[]={0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00};
 static uae_u8 bootblock_ofs[]={
@@ -2561,51 +2561,55 @@ int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck)
 {
        int i;
 
-       if (idx >= MAX_PREVIOUS_FLOPPIES)
+       if (idx >= MAX_PREVIOUS_IMAGES)
                return 0;
        if (name == NULL) {
+               if (idx < 0)
+                       return 0;
                dfxhistory[type][idx][0] = 0;
                return 1;
        }
        if (name[0] == 0)
                return 0;
+#if 0
        if (!donotcheck) {
                if (!zfile_exists (name)) {
-                       for (i = 0; i < MAX_PREVIOUS_FLOPPIES; i++) {
+                       for (i = 0; i < MAX_PREVIOUS_IMAGES; i++) {
                                if (!_tcsicmp (dfxhistory[type][i], name)) {
-                                       while (i < MAX_PREVIOUS_FLOPPIES - 1) {
+                                       while (i < MAX_PREVIOUS_IMAGES - 1) {
                                                _tcscpy (dfxhistory[type][i], dfxhistory[type][i + 1]);
                                                i++;
                                        }
-                                       dfxhistory[type][MAX_PREVIOUS_FLOPPIES - 1][0] = 0;
+                                       dfxhistory[type][MAX_PREVIOUS_IMAGES - 1][0] = 0;
                                        break;
                                }
                        }
                        return 0;
                }
        }
+#endif
        if (idx >= 0) {
-               if (idx >= MAX_PREVIOUS_FLOPPIES)
+               if (idx >= MAX_PREVIOUS_IMAGES)
                        return 0;
                dfxhistory[type][idx][0] = 0;
-               for (i = 0; i < MAX_PREVIOUS_FLOPPIES; i++) {
+               for (i = 0; i < MAX_PREVIOUS_IMAGES; i++) {
                        if (!_tcsicmp (dfxhistory[type][i], name))
                                return 0;
                }
                _tcscpy (dfxhistory[type][idx], name);
                return 1;
        }
-       for (i = 0; i < MAX_PREVIOUS_FLOPPIES; i++) {
+       for (i = 0; i < MAX_PREVIOUS_IMAGES; i++) {
                if (!_tcscmp (dfxhistory[type][i], name)) {
-                       while (i < MAX_PREVIOUS_FLOPPIES - 1) {
+                       while (i < MAX_PREVIOUS_IMAGES - 1) {
                                _tcscpy (dfxhistory[type][i], dfxhistory[type][i + 1]);
                                i++;
                        }
-                       dfxhistory[type][MAX_PREVIOUS_FLOPPIES - 1][0] = 0;
+                       dfxhistory[type][MAX_PREVIOUS_IMAGES - 1][0] = 0;
                        break;
                }
        }
-       for (i = MAX_PREVIOUS_FLOPPIES - 2; i >= 0; i--)
+       for (i = MAX_PREVIOUS_IMAGES - 2; i >= 0; i--)
                _tcscpy (dfxhistory[type][i + 1], dfxhistory[type][i]);
        _tcscpy (dfxhistory[type][0], name);
        return 1;
@@ -2613,7 +2617,7 @@ int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck)
 
 TCHAR *DISK_history_get (int idx, int type)
 {
-       if (idx >= MAX_PREVIOUS_FLOPPIES)
+       if (idx >= MAX_PREVIOUS_IMAGES)
                return NULL;
        return dfxhistory[type][idx];
 }
@@ -3512,7 +3516,10 @@ void DSKLEN (uae_u16 v, int hpos)
 
        DISK_update (hpos);
 
-       if ((v & 0x8000) && (dsklen & 0x8000)) {
+       dsklen = v;
+       dsklength2 = dsklength = dsklen & 0x3fff;
+
+       if ((dsklen & 0x8000) && (prev & 0x8000)) {
                dskdmaen = DSKDMA_READ;
                DISK_start ();
        }
@@ -3534,8 +3541,6 @@ void DSKLEN (uae_u16 v, int hpos)
                        dskdmaen = DSKDMA_OFF;
                }
        }
-       dsklen = v;
-       dsklength2 = dsklength = dsklen & 0x3fff;
 
        if (dskdmaen == DSKDMA_OFF)
                return;
index d0d20fee075f8840cc82326b027f0c862ce9260c..7456e8caaec81a39c0b51876a4a840dccd02fc82 100644 (file)
@@ -743,6 +743,7 @@ PLAYFIELD_START and PLAYFIELD_END are in window coordinates.  */
 static int playfield_start, playfield_end;
 static int real_playfield_start, real_playfield_end;
 static int sprite_playfield_start;
+static bool may_require_hard_way;
 static int linetoscr_diw_start, linetoscr_diw_end;
 static int native_ddf_left, native_ddf_right;
 
@@ -850,6 +851,7 @@ static void pfield_init_linetoscr (bool border)
        }
 
 #ifdef AGA
+       may_require_hard_way = false;
        if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank && dip_for_drawing->nr_sprites) {
                int min = visible_right_border, max = visible_left_border, i;
                for (i = 0; i < dip_for_drawing->nr_sprites; i++) {
@@ -873,6 +875,8 @@ static void pfield_init_linetoscr (bool border)
                        playfield_end = max;
                if (playfield_end > visible_right_border)
                        playfield_end = visible_right_border;
+               sprite_playfield_start = 0;
+               may_require_hard_way = true;
        }
 #endif
 
@@ -1930,6 +1934,10 @@ static void weird_bitplane_fix (int start, int end)
        }
 }
 
+/* We use the compiler's inlining ability to ensure that PLANES is in effect a compile time
+constant.  That will cause some unnecessary code to be optimized away.
+Don't touch this if you don't know what you are doing.  */
+
 #define MERGE(a,b,mask,shift) do {\
        uae_u32 tmp = mask & (a ^ (b >> shift)); \
        a ^= tmp; \
@@ -1938,9 +1946,6 @@ static void weird_bitplane_fix (int start, int end)
 
 #define GETLONG(P) (*(uae_u32 *)P)
 
-/* We use the compiler's inlining ability to ensure that PLANES is in effect a compile time
-constant.  That will cause some unnecessary code to be optimized away.
-Don't touch this if you don't know what you are doing.  */
 STATIC_INLINE void pfield_doline_1 (uae_u32 *pixels, int wordcount, int planes)
 {
        while (wordcount-- > 0) {
@@ -2303,6 +2308,24 @@ static void adjust_drawing_colors (int ctable, int need_full)
        }
 }
 
+static void playfield_hard_way(line_draw_func worker_pfield, int first, int last)
+{
+       if (first < real_playfield_start)  {
+               int next = last < real_playfield_start ? last : real_playfield_start;
+               int diff = next - first;
+               pfield_do_linetoscr_bordersprite_aga(first, next, false);
+               if (res_shift >= 0)
+                       diff >>= res_shift;
+               else
+                       diff <<= res_shift;
+               src_pixel += diff;
+               first = next;
+       }
+       (*worker_pfield)(first, last < real_playfield_end ? last : real_playfield_end, false);
+       if (last > real_playfield_end)
+               pfield_do_linetoscr_bordersprite_aga(real_playfield_end, last, false);
+}
+
 static void do_color_changes (line_draw_func worker_border, line_draw_func worker_pfield, int vp)
 {
        int i;
@@ -2342,7 +2365,10 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
                        int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
                        if (plf2pri > 5 && bplplanecnt == 5 && !(currprefs.chipset_mask & CSMASK_AGA))
                                weird_bitplane_fix (lastpos, t);
-                       (*worker_pfield) (lastpos, t, false);
+                       if (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga)
+                               playfield_hard_way(worker_pfield, lastpos, t);
+                       else
+                               (*worker_pfield) (lastpos, t, false);
                        lastpos = t;
                }
 
index cea325b87710cd91ae7d509ddbc813e223f85fab..2c5edb0ee3431e9868e8d3bb1823dd0419c26551 100644 (file)
@@ -9,8 +9,6 @@
 *
 */
 
-//#define EXP_DEBUG
-
 #include "sysconfig.h"
 #include "sysdeps.h"
 
@@ -25,6 +23,7 @@
 #include "zfile.h"
 #include "catweasel.h"
 #include "cdtv.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "a2065.h"
 #include "gfxboard.h"
@@ -143,6 +142,7 @@ static bool chipdone;
 static void (*card_init[MAX_EXPANSION_BOARDS]) (void);
 static void (*card_map[MAX_EXPANSION_BOARDS]) (void);
 static TCHAR *card_name[MAX_EXPANSION_BOARDS];
+static int card_flags[MAX_EXPANSION_BOARDS];
 
 static int ecard, cardno, z3num;
 
@@ -237,10 +237,23 @@ static void REGPARAM3 expamem_lput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 expamem_wput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 expamem_bput (uaecptr, uae_u32) REGPARAM;
 
+static uae_u32 REGPARAM3 expamemz3_lget (uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 expamemz3_wget (uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 expamemz3_bget (uaecptr) REGPARAM;
+static void REGPARAM3 expamemz3_lput (uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 expamemz3_wput (uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 expamemz3_bput (uaecptr, uae_u32) REGPARAM;
+
 addrbank expamem_bank = {
        expamem_lget, expamem_wget, expamem_bget,
        expamem_lput, expamem_wput, expamem_bput,
-       default_xlate, default_check, NULL, _T("Autoconfig"),
+       default_xlate, default_check, NULL, _T("Autoconfig Z2"),
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+addrbank expamemz3_bank = {
+       expamemz3_lget, expamemz3_wget, expamemz3_bget,
+       expamemz3_lput, expamemz3_wput, expamemz3_bput,
+       default_xlate, default_check, NULL, _T("Autoconfig Z3"),
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
@@ -257,11 +270,14 @@ static void expamem_init_clear (void)
 static void expamem_init_clear_zero (void)
 {
        map_banks (&dummy_bank, 0xe8, 1, 0);
+       if (!currprefs.address_space_24)
+               map_banks (&dummy_bank, 0xff000000 >> 16, 1, 0);
 }
 
 static void expamem_init_clear2 (void)
 {
-       expamem_bank.name = _T("Autoconfig");
+       expamem_bank.name = _T("Autoconfig Z2");
+       expamemz3_bank.name = _T("Autoconfig Z3");
        expamem_init_clear_zero ();
        ecard = cardno;
 }
@@ -276,8 +292,17 @@ static void expamem_init_last (void)
 void expamem_next (void)
 {
        expamem_init_clear ();
-       map_banks (&expamem_bank, 0xE8, 1, 0);
        ++ecard;
+
+       if ((card_flags[ecard] & 1) && currprefs.cs_z3autoconfig) {
+               map_banks (&expamemz3_bank, 0xff000000 >> 16, 1, 0);
+               map_banks (&dummy_bank, 0xE8, 1, 0);
+       } else {
+               map_banks (&expamem_bank, 0xE8, 1, 0);
+               if (currprefs.address_space_24)
+                       map_banks (&dummy_bank, 0xff000000 >> 16, 1, 0);
+       }
+
        if (ecard < cardno) {
                expamem_bank.name = card_name[ecard] ? card_name[ecard] : (TCHAR*) _T("None");
                (*card_init[ecard]) ();
@@ -286,9 +311,14 @@ void expamem_next (void)
        }
 }
 
+static int REGPARAM2 expamem_type (void)
+{
+       return ((expamem[0] | expamem[2] >> 4) & 0xc0);
+}
+
 static uae_u32 REGPARAM2 expamem_lget (uaecptr addr)
 {
-       write_log (_T("warning: READ.L from address $%lx PC=%x\n"), addr, M68K_GETPC);
+       write_log (_T("warning: Z2 READ.L from address $%lx PC=%x\n"), addr, M68K_GETPC);
        return (expamem_wget (addr) << 16) | expamem_wget (addr + 2);
 }
 
@@ -332,17 +362,12 @@ static void REGPARAM2 expamem_write (uaecptr addr, uae_u32 value)
        }
 }
 
-static int REGPARAM2 expamem_type (void)
-{
-       return ((expamem[0] | expamem[2] >> 4) & 0xc0);
-}
-
 static void REGPARAM2 expamem_lput (uaecptr addr, uae_u32 value)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       write_log (_T("warning: WRITE.L to address $%lx : value $%lx\n"), addr, value);
+       write_log (_T("warning: Z2 WRITE.L to address $%lx : value $%lx\n"), addr, value);
 }
 
 static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
@@ -356,16 +381,15 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
        value &= 0xffff;
        if (ecard >= cardno)
                return;
-       if (expamem_type () != zorroIII)
+       if (expamem_type () != zorroIII) {
                write_log (_T("warning: WRITE.W to address $%lx : value $%x\n"), addr, value);
-       else {
+       else {
                switch (addr & 0xff) {
                case 0x44:
                        if (expamem_type () == zorroIII) {
                                if (currprefs.jit_direct_compatible_memory) {
-                                       uae_u32 p1, p2 = 0;
+                                       uae_u32 p2 = 0;
                                        // +Bernd Roesch & Toni Wilen
-                                       p1 = get_word (regs.regs[11] + 0x20);
                                        if (expamem[0] & add_memory) {
                                                // Z3 RAM expansion
                                                p2 = 0;
@@ -383,14 +407,16 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
                                                if (gfxmem_bank.start & 0xff000000)
                                                        p2 = gfxmem_bank.start >> 16;
                                        }
-                                       put_word (regs.regs[11] + 0x20, p2);
-                                       put_word (regs.regs[11] + 0x28, p2);
+                                       if (value != p2) {
+                                               put_word (regs.regs[11] + 0x20, p2);
+                                               put_word (regs.regs[11] + 0x28, p2);
+                                       }
                                        // -Bernd Roesch
                                        expamem_hi = p2;
+                                       expamem_lo = 0;
                                        (*card_map[ecard]) ();
-                                       if (p1 != p2)
-                                               write_log (_T("   Card %d remapped %04x0000 -> %04x0000\n"), ecard + 1, p1, p2);
                                } else {
+                                       expamem_lo = 0;
                                        expamem_hi = value & 0xff00;
                                        (*card_map[ecard]) ();
                                }
@@ -450,6 +476,49 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
        }
 }
 
+static uae_u32 REGPARAM2 expamemz3_bget (uaecptr addr)
+{
+       int reg = addr & 0xff;
+       if (addr & 0x100)
+               return expamem_bget(reg + 2);
+       else
+               return expamem_bget(reg + 0);
+}
+static uae_u32 REGPARAM2 expamemz3_wget (uaecptr addr)
+{
+       uae_u32 v = (expamemz3_bget (addr) << 8) | expamemz3_bget (addr + 1);
+       write_log (_T("warning: Z3 READ.W from address $%lx=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC);
+       return v;
+}
+static uae_u32 REGPARAM2 expamemz3_lget (uaecptr addr)
+{
+       write_log (_T("warning: Z3 READ.L from address $%lx PC=%x\n"), addr, M68K_GETPC);
+       return (expamemz3_wget (addr) << 16) | expamemz3_wget (addr + 2);
+}
+static void REGPARAM2 expamemz3_bput (uaecptr addr, uae_u32 value)
+{
+       int reg = addr & 0xff;
+       if (addr & 0x100)
+               expamem_bget(reg + 2);
+       else
+               expamem_bget(reg + 0);
+}
+static void REGPARAM2 expamemz3_wput (uaecptr addr, uae_u32 value)
+{
+       int reg = addr & 0xff;
+       if (addr & 0x100)
+               expamem_wput(reg + 2, value);
+       else
+               expamem_wput(reg + 0, value);
+}
+static void REGPARAM2 expamemz3_lput (uaecptr addr, uae_u32 value)
+{
+#ifdef JIT
+       special_mem |= S_WRITE;
+#endif
+       write_log (_T("warning: Z3 WRITE.L to address $%lx : value $%lx\n"), addr, value);
+}
+
 #ifdef CD32
 
 static void expamem_map_cd32fmv (void)
@@ -487,6 +556,9 @@ static void expamem_init_cd32fmv (void)
 
 
 MEMORY_FUNCTIONS(fastmem);
+MEMORY_FUNCTIONS_NOJIT(fastmem_nojit);
+MEMORY_FUNCTIONS(fastmem2);
+MEMORY_FUNCTIONS_NOJIT(fastmem2_nojit);
 
 addrbank fastmem_bank = {
        fastmem_lget, fastmem_wget, fastmem_bget,
@@ -494,7 +566,32 @@ addrbank fastmem_bank = {
        fastmem_xlate, fastmem_check, NULL, _T("Fast memory"),
        fastmem_lget, fastmem_wget, ABFLAG_RAM
 };
+addrbank fastmem_nojit_bank = {
+       fastmem_nojit_lget, fastmem_nojit_wget, fastmem_bget,
+       fastmem_nojit_lput, fastmem_nojit_wput, fastmem_bput,
+       fastmem_nojit_xlate, fastmem_nojit_check, NULL, _T("Fast memory (nojit)"),
+       fastmem_nojit_lget, fastmem_nojit_wget, ABFLAG_RAM
+};
+addrbank fastmem2_bank = {
+       fastmem2_lget, fastmem2_wget, fastmem2_bget,
+       fastmem2_lput, fastmem2_wput, fastmem2_bput,
+       fastmem2_xlate, fastmem2_check, NULL, _T("Fast memory 2"),
+       fastmem2_lget, fastmem2_wget, ABFLAG_RAM
+};
+addrbank fastmem2_nojit_bank = {
+       fastmem2_nojit_lget, fastmem2_nojit_wget, fastmem2_nojit_bget,
+       fastmem2_nojit_lput, fastmem2_nojit_wput, fastmem2_nojit_bput,
+       fastmem2_nojit_xlate, fastmem2_nojit_check, NULL, _T("Fast memory #2 (nojit)"),
+       fastmem2_nojit_lget, fastmem2_nojit_wget, ABFLAG_RAM
+};
 
+static addrbank *fastbanks[] = 
+{
+       &fastmem_bank,
+       &fastmem_nojit_bank,
+       &fastmem2_bank,
+       &fastmem2_nojit_bank
+};
 
 #ifdef CATWEASEL
 
@@ -748,37 +845,49 @@ addrbank z3chipmem_bank = {
        z3chipmem_lget, z3chipmem_wget, ABFLAG_RAM
 };
 
-/* Z3-based UAEGFX-card */
-
 /* ********************************************************** */
 
 /*
-*     Expansion Card (ZORRO II) for 1/2/4/8 MB of Fast Memory
+*     Expansion Card (ZORRO II) for 64/128/256/512KB 1/2/4/8MB of Fast Memory
 */
 
-static void expamem_map_fastcard (void)
-{
-       fastmem_bank.start = ((expamem_hi | (expamem_lo >> 4)) << 16);
-       if (fastmem_bank.start) {
-               map_banks (&fastmem_bank, fastmem_bank.start >> 16, fastmem_bank.allocated >> 16, 0);
-               write_log (_T("Fastcard: mapped @$%lx: %dMB fast memory\n"), fastmem_bank.start, fastmem_bank.allocated >> 20);
+static void expamem_map_fastcard_2 (int boardnum)
+{
+       uae_u32 start = ((expamem_hi | (expamem_lo >> 4)) << 16);
+       addrbank *ab = fastbanks[boardnum * 2 + ((start < 0x00A00000) ? 0 : 1)];
+       ab->start = start;
+       if (ab->start) {
+               map_banks (ab, ab->start >> 16, ab->allocated >> 16, 0);
+               if (ab->allocated <= 524288)
+               write_log (_T("%s: mapped @$%lx: %dKB fast memory\n"), ab->name, ab->start, ab->allocated >> 10);
+               else
+               write_log (_T("%s: mapped @$%lx: %dMB fast memory\n"), ab->name, ab->start, ab->allocated >> 20);
        }
 }
 
-static void expamem_init_fastcard (void)
+static void expamem_init_fastcard_2 (int boardnum)
 {
        uae_u16 mid = (currprefs.a2091 || currprefs.uae_hide) ? commodore : uae_id;
        uae_u8 pid = (currprefs.a2091 || currprefs.uae_hide) ? commodore_a2091_ram : (currprefs.maprom ? 1 : 81);
-       uae_u8 type = add_memory | zorroII | (currprefs.a2091 ? chainedconfig : 0);
+       uae_u8 type = add_memory | zorroII | (currprefs.a2091 && !boardnum ? chainedconfig : 0);
+       int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated;
 
        expamem_init_clear ();
-       if (fastmem_bank.allocated == 0x100000)
+       if (allocated == 65536)
+               type |= Z2_MEM_64KB;
+       else if (allocated == 131072)
+               type |= Z2_MEM_128KB;
+       else if (allocated == 262144)
+               type |= Z2_MEM_256KB;
+       else if (allocated == 524288)
+               type |= Z2_MEM_512KB;
+       else if (allocated == 0x100000)
                type |= Z2_MEM_1MB;
-       else if (fastmem_bank.allocated == 0x200000)
+       else if (allocated == 0x200000)
                type |= Z2_MEM_2MB;
-       else if (fastmem_bank.allocated == 0x400000)
+       else if (allocated == 0x400000)
                type |= Z2_MEM_4MB;
-       else if (fastmem_bank.allocated == 0x800000)
+       else if (allocated == 0x800000)
                type |= Z2_MEM_8MB;
 
        expamem_write (0x00, type);
@@ -801,6 +910,23 @@ static void expamem_init_fastcard (void)
        expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
 }
 
+static void expamem_map_fastcard (void)
+{
+       expamem_map_fastcard_2 (0);
+}
+static void expamem_map_fastcard2 (void)
+{
+       expamem_map_fastcard_2 (1);
+}
+static void expamem_init_fastcard (void)
+{
+       expamem_init_fastcard_2 (0);
+}
+static void expamem_init_fastcard2 (void)
+{
+       expamem_init_fastcard_2 (1);
+}
+
 /* ********************************************************** */
 
 #ifdef FILESYS
@@ -943,7 +1069,7 @@ static void expamem_init_z3fastmem_2 (addrbank *bank, uae_u32 start, uae_u32 siz
        expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
        expamem_write (0x24, 0x01); /* ser.no. Byte 3 */
 
-       expamem_write (0x28, 0x00); /* Rom-Offset hi */
+       expamem_write (0x28, 0x00); /* ROM-Offset hi */
        expamem_write (0x2c, 0x00); /* ROM-Offset lo */
 
        expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
@@ -970,7 +1096,7 @@ static void expamem_map_gfxcard (void)
        gfxmem_bank.start = (expamem_hi | (expamem_lo >> 4)) << 16;
        if (gfxmem_bank.start) {
                map_banks (&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16, gfxmem_bank.allocated);
-               write_log (_T("%sUAEGFX-card: mapped @$%lx, %d MB RTG RAM\n"), currprefs.rtgmem_type ? _T("Z3") : _T("Z2"), gfxmem_bank.baseaddr, gfxmem_bank.allocated / 0x100000);
+               write_log (_T("%sUAEGFX-card: mapped @$%lx, %d MB RTG RAM\n"), currprefs.rtgmem_type ? _T("Z3") : _T("Z2"), gfxmem_bank.start, gfxmem_bank.allocated / 0x100000);
        }
 }
 
@@ -1027,14 +1153,20 @@ static void expamem_init_gfxcard_z2 (void)
 
 
 #ifdef SAVESTATE
-static size_t fast_filepos, z3_filepos, z3_filepos2, z3_fileposchip, p96_filepos;
+static size_t fast_filepos, fast2_filepos, z3_filepos, z3_filepos2, z3_fileposchip, p96_filepos;
 #endif
 
-void free_fastmemory (void)
+void free_fastmemory (int boardnum)
 {
-       if (fastmem_bank.baseaddr)
-               mapped_free (fastmem_bank.baseaddr);
-       fastmem_bank.baseaddr = 0;
+       if (!boardnum) {
+               if (fastmem_bank.baseaddr)
+                       mapped_free (fastmem_bank.baseaddr);
+               fastmem_bank.baseaddr = 0;
+       } else {
+               if (fastmem2_bank.baseaddr)
+                       mapped_free (fastmem2_bank.baseaddr);
+               fastmem2_bank.baseaddr = 0;
+       }
 }
 
 static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *name)
@@ -1076,31 +1208,64 @@ static void allocate_expamem (void)
        currprefs.rtgmem_type = changed_prefs.rtgmem_type;
        currprefs.z3chipmem_size = changed_prefs.z3chipmem_size;
 
-       z3chipmem_bank.start = currprefs.z3fastmem_start;
+       z3chipmem_bank.start = 0x10000000;
+       z3fastmem_bank.start = currprefs.z3fastmem_start;
        if (currprefs.mbresmem_high_size == 128 * 1024 * 1024)
                z3chipmem_bank.start += 16 * 1024 * 1024;
-       if (currprefs.jit_direct_compatible_memory)
-               z3fastmem_bank.start = z3chipmem_bank.start;
-       else
+       if (!currprefs.jit_direct_compatible_memory)
                z3fastmem_bank.start = 0x40000000;
-       if (currprefs.z3chipmem_size)
+       if (z3fastmem_bank.start == 0x10000000) {
+               if (currprefs.mbresmem_high_size == 128 * 1024 * 1024)
+                       z3fastmem_bank.start += 16 * 1024 * 1024;
                z3fastmem_bank.start += currprefs.z3chipmem_size;
+       }
        z3fastmem2_bank.start = z3fastmem_bank.start + currprefs.z3fastmem_size;
 
+       if (currprefs.z3chipmem_size && z3fastmem_bank.start - z3chipmem_bank.start < currprefs.z3chipmem_size)
+               currprefs.z3chipmem_size = changed_prefs.z3chipmem_size = 0;    
+
        if (fastmem_bank.allocated != currprefs.fastmem_size) {
-               free_fastmemory ();
+               free_fastmemory (0);
+
                fastmem_bank.allocated = currprefs.fastmem_size;
                fastmem_bank.mask = fastmem_bank.allocated - 1;
 
+               fastmem_nojit_bank.allocated = fastmem_bank.allocated;
+               fastmem_nojit_bank.mask = fastmem_bank.mask;
+
                if (fastmem_bank.allocated) {
                        fastmem_bank.baseaddr = mapped_malloc (fastmem_bank.allocated, _T("fast"));
+                       fastmem_nojit_bank.baseaddr = fastmem_bank.baseaddr;
                        if (fastmem_bank.baseaddr == 0) {
                                write_log (_T("Out of memory for fastmem card.\n"));
                                fastmem_bank.allocated = 0;
+                               fastmem_nojit_bank.allocated = 0;
+                       }
+               }
+               memory_hardreset (1);
+       }
+
+       if (fastmem2_bank.allocated != currprefs.fastmem2_size) {
+               free_fastmemory (1);
+
+               fastmem2_bank.allocated = currprefs.fastmem2_size;
+               fastmem2_bank.mask = fastmem2_bank.allocated - 1;
+
+               fastmem2_nojit_bank.allocated = fastmem2_bank.allocated;
+               fastmem2_nojit_bank.mask = fastmem2_bank.mask;
+
+               if (fastmem2_bank.allocated) {
+                       fastmem2_bank.baseaddr = mapped_malloc (fastmem2_bank.allocated, _T("fast2"));
+                       fastmem2_nojit_bank.baseaddr = fastmem2_bank.baseaddr;
+                       if (fastmem2_bank.baseaddr == 0) {
+                               write_log (_T("Out of memory for fastmem2 card.\n"));
+                               fastmem2_bank.allocated = 0;
+                               fastmem2_nojit_bank.allocated = 0;
                        }
                }
                memory_hardreset (1);
        }
+
        if (z3fastmem_bank.allocated != currprefs.z3fastmem_size) {
                if (z3fastmem_bank.baseaddr)
                        mapped_free (z3fastmem_bank.baseaddr);
@@ -1147,6 +1312,11 @@ static void allocate_expamem (void)
                        map_banks (&fastmem_bank, fastmem_bank.start >> 16, currprefs.fastmem_size >> 16,
                                fastmem_bank.allocated);
                }
+               if (fastmem2_bank.allocated > 0) {
+                       restore_ram (fast2_filepos, fastmem2_bank.baseaddr);
+                       map_banks (&fastmem2_bank, fastmem2_bank.start >> 16, currprefs.fastmem2_size >> 16,
+                               fastmem2_bank.allocated);
+               }
                if (z3fastmem_bank.allocated > 0) {
                        restore_ram (z3_filepos, z3fastmem_bank.baseaddr);
                        map_banks (&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16,
@@ -1201,7 +1371,7 @@ static uaecptr check_boot_rom (void)
                return b;
        if (currprefs.input_tablet > 0)
                return b;
-       if (currprefs.rtgmem_size)
+       if (currprefs.rtgmem_size && currprefs.rtgmem_type < GFXBOARD_HARDWARE)
                return b;
        if (currprefs.win32_automount_removable)
                return b;
@@ -1242,13 +1412,25 @@ static void expamem_init_cdtv (void)
 static void expamem_init_a2091 (void)
 {
 #ifdef A2091
-       a2091_init ();
+       a2091_init (0);
+#endif
+}
+static void expamem_init_a2091_2 (void)
+{
+#ifdef A2091
+       a2091_init (1);
 #endif
 }
 static void expamem_init_a4091 (void)
 {
 #ifdef NCR
-       ncr_autoconfig_init ();
+       ncr_autoconfig_init (0);
+#endif
+}
+static void expamem_init_a4091_2 (void)
+{
+#ifdef NCR
+       ncr_autoconfig_init (1);
 #endif
 }
 static void expamem_init_gfxboard_memory (void)
@@ -1294,27 +1476,44 @@ void expamem_reset (void)
        if (need_uae_boot_rom () == 0)
                do_mount = 0;
 
-       if (fastmem_bank.baseaddr != NULL && currprefs.chipmem_size <= 2 * 1024 * 1024) {
-               if (currprefs.fastmem_autoconfig) {
-                       fastmem_bank.name = _T("Fast memory");
+       if (currprefs.fastmem_autoconfig) {
+               if (fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
+                       card_flags[cardno] = 0;
                        card_name[cardno] = _T("Z2Fast");
                        card_init[cardno] = expamem_init_fastcard;
                        card_map[cardno++] = expamem_map_fastcard;
-               } else {
+               }
+               if (fastmem2_bank.baseaddr != NULL && (fastmem2_bank.allocated <= 262144  || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
+                       card_flags[cardno] = 0;
+                       card_name[cardno] = _T("Z2Fast2");
+                       card_init[cardno] = expamem_init_fastcard2;
+                       card_map[cardno++] = expamem_map_fastcard2;
+               }
+       } else {
+               if (fastmem_bank.baseaddr) {
                        fastmem_bank.name = _T("Fast memory (non-autoconfig)");
                        map_banks (&fastmem_bank, 0x00200000 >> 16, fastmem_bank.allocated >> 16, 0);
                }
+               if (fastmem2_bank.baseaddr != NULL) {
+                       fastmem2_bank.name = _T("Fast memory 2 (non-autoconfig)");
+                       map_banks(&fastmem2_bank, (0x00200000 + fastmem2_bank.allocated) >> 16, fastmem2_bank.allocated >> 16, 0);
+               }
        }
        // immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram.
 #ifdef A2091
        if (currprefs.a2091) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("A2091");
                card_init[cardno] = expamem_init_a2091;
                card_map[cardno++] = NULL;
+               card_name[cardno] = _T("A2091 #2");
+               card_init[cardno] = expamem_init_a2091_2;
+               card_map[cardno++] = NULL;
        }
 #endif
 #ifdef CDTV
        if (currprefs.cs_cdtvcd) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("CDTV DMAC");
                card_init[cardno] = expamem_init_cdtv;
                card_map[cardno++] = NULL;
@@ -1325,6 +1524,7 @@ void expamem_reset (void)
                int ids[] = { 23, -1 };
                struct romlist *rl = getromlistbyids (ids);
                if (rl && !_tcscmp (rl->path, currprefs.cartfile)) {
+                       card_flags[cardno] = 0;
                        card_name[cardno] = _T("CD32MPEG");
                        card_init[cardno] = expamem_init_cd32fmv;
                        card_map[cardno++] = expamem_map_cd32fmv;
@@ -1333,6 +1533,7 @@ void expamem_reset (void)
 #endif
 #ifdef A2065
        if (currprefs.a2065name[0]) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("A2065");
                card_init[cardno] = expamem_init_a2065;
                card_map[cardno++] = NULL;
@@ -1340,6 +1541,7 @@ void expamem_reset (void)
 #endif
 #ifdef FILESYS
        if (do_mount) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("UAEFS");
                card_init[cardno] = expamem_init_filesys;
                card_map[cardno++] = expamem_map_filesys;
@@ -1347,6 +1549,7 @@ void expamem_reset (void)
 #endif
 #ifdef CATWEASEL
        if (currprefs.catweasel && catweasel_init ()) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("CWMK2");
                card_init[cardno] = expamem_init_catweasel;
                card_map[cardno++] = expamem_map_catweasel;
@@ -1354,6 +1557,7 @@ void expamem_reset (void)
 #endif
 #ifdef PICASSO96
        if (currprefs.rtgmem_type == GFXBOARD_UAE_Z2 && gfxmem_bank.baseaddr != NULL) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("Z2RTG");
                card_init[cardno] = expamem_init_gfxcard_z2;
                card_map[cardno++] = expamem_map_gfxcard;
@@ -1361,15 +1565,18 @@ void expamem_reset (void)
 #endif
 #ifdef GFXBOARD
        if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && !gfxboard_is_z3 (currprefs.rtgmem_type)) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("Gfxboard VRAM Zorro II");
                card_init[cardno] = expamem_init_gfxboard_memory;
                card_map[cardno++] = NULL;
                if (gfxboard_num_boards (currprefs.rtgmem_type) == 3) {
+                       card_flags[cardno] = 0;
                        card_name[cardno] = _T("Gfxboard VRAM Zorro II Extra");
                        card_init[cardno] = gfxboard_init_memory_p4_z2;
                        card_map[cardno++] = NULL;
                }
                if (gfxboard_is_registers (currprefs.rtgmem_type)) {
+                       card_flags[cardno] = 0;
                        card_name[cardno] = _T ("Gfxboard Registers");
                        card_init[cardno] = expamem_init_gfxboard_registers;
                        card_map[cardno++] = NULL;
@@ -1380,12 +1587,14 @@ void expamem_reset (void)
 
        if (z3fastmem_bank.baseaddr != NULL) {
                z3num = 0;
+               card_flags[cardno] = 1;
                card_name[cardno] = _T("Z3Fast");
                card_init[cardno] = expamem_init_z3fastmem;
                card_map[cardno++] = expamem_map_z3fastmem;
                if (currprefs.jit_direct_compatible_memory)
                        map_banks (&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16, z3fastmem_bank.allocated);
                if (z3fastmem2_bank.baseaddr != NULL) {
+                       card_flags[cardno] = 1;
                        card_name[cardno] = _T("Z3Fast2");
                        card_init[cardno] = expamem_init_z3fastmem2;
                        card_map[cardno++] = expamem_map_z3fastmem2;
@@ -1395,15 +1604,9 @@ void expamem_reset (void)
        }
        if (z3chipmem_bank.baseaddr != NULL)
                map_banks (&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16, z3chipmem_bank.allocated);
-#ifdef NCR
-       if (currprefs.a4091) {
-               card_name[cardno] = _T("A4091");
-               card_init[cardno] = expamem_init_a4091;
-               card_map[cardno++] = NULL;
-       }
-#endif
 #ifdef PICASSO96
        if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) {
+               card_flags[cardno] = 1;
                card_name[cardno] = _T("Z3RTG");
                card_init[cardno] = expamem_init_gfxcard_z3;
                card_map[cardno++] = expamem_map_gfxcard;
@@ -1411,6 +1614,7 @@ void expamem_reset (void)
 #endif
 #ifdef GFXBOARD
        if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_is_z3 (currprefs.rtgmem_type)) {
+               card_flags[cardno] = 1;
                card_name[cardno] = _T ("Gfxboard VRAM Zorro III");
                card_init[cardno] = expamem_init_gfxboard_memory;
                card_map[cardno++] = NULL;
@@ -1418,8 +1622,20 @@ void expamem_reset (void)
                card_init[cardno] = expamem_init_gfxboard_registers;
                card_map[cardno++] = NULL;
        }
+#endif
+#ifdef NCR
+       if (currprefs.a4091) {
+               card_flags[cardno] = 1;
+               card_name[cardno] = _T("A4091");
+               card_init[cardno] = expamem_init_a4091;
+               card_map[cardno++] = NULL;
+               card_name[cardno] = _T("A4091 #2");
+               card_init[cardno] = expamem_init_a4091_2;
+               card_map[cardno++] = NULL;
+       }
 #endif
        if (cardno > 0 && cardno < MAX_EXPANSION_BOARDS) {
+               card_flags[cardno] = 0;
                card_name[cardno] = _T("Empty");
                card_init[cardno] = expamem_init_last;
                card_map[cardno++] = expamem_map_clear;
@@ -1438,6 +1654,16 @@ void expansion_init (void)
                fastmem_bank.allocated = 0;
                fastmem_bank.mask = fastmem_bank.start = 0;
                fastmem_bank.baseaddr = NULL;
+               fastmem_nojit_bank.allocated = 0;
+               fastmem_nojit_bank.mask = fastmem_nojit_bank.start = 0;
+               fastmem_nojit_bank.baseaddr = NULL;
+
+               fastmem2_bank.allocated = 0;
+               fastmem2_bank.mask = fastmem2_bank.start = 0;
+               fastmem2_bank.baseaddr = NULL;
+               fastmem2_nojit_bank.allocated = 0;
+               fastmem2_nojit_bank.mask = fastmem2_nojit_bank.start = 0;
+               fastmem2_nojit_bank.baseaddr = NULL;
 
 #ifdef PICASSO96
                gfxmem_bank.allocated = 0;
@@ -1452,9 +1678,11 @@ void expansion_init (void)
                z3fastmem_bank.allocated = 0;
                z3fastmem_bank.mask = z3fastmem_bank.start = 0;
                z3fastmem_bank.baseaddr = NULL;
+
                z3fastmem2_bank.allocated = 0;
                z3fastmem2_bank.mask = z3fastmem2_bank.start = 0;
                z3fastmem2_bank.baseaddr = NULL;
+
                z3chipmem_bank.allocated = 0;
                z3chipmem_bank.mask = z3chipmem_bank.start = 0;
                z3chipmem_bank.baseaddr = NULL;
@@ -1481,6 +1709,10 @@ void expansion_cleanup (void)
 {
        mapped_free (fastmem_bank.baseaddr);
        fastmem_bank.baseaddr = NULL;
+       fastmem_nojit_bank.baseaddr = NULL;
+       mapped_free (fastmem2_bank.baseaddr);
+       fastmem2_bank.baseaddr = NULL;
+       fastmem2_nojit_bank.baseaddr = NULL;
        mapped_free (z3fastmem_bank.baseaddr);
        z3fastmem_bank.baseaddr = NULL;
        mapped_free (z3fastmem2_bank.baseaddr);
@@ -1513,6 +1745,7 @@ static void clear_bank (addrbank *ab)
 void expansion_clear (void)
 {
        clear_bank (&fastmem_bank);
+       clear_bank (&fastmem2_bank);
        clear_bank (&z3fastmem_bank);
        clear_bank (&z3fastmem2_bank);
        clear_bank (&z3chipmem_bank);
@@ -1523,10 +1756,15 @@ void expansion_clear (void)
 
 /* State save/restore code.  */
 
-uae_u8 *save_fram (int *len)
+uae_u8 *save_fram (int *len, int num)
 {
-       *len = fastmem_bank.allocated;
-       return fastmem_bank.baseaddr;
+       if (num) {
+               *len = fastmem2_bank.allocated;
+               return fastmem2_bank.baseaddr;
+       } else {
+               *len = fastmem_bank.allocated;
+               return fastmem_bank.baseaddr;
+       }
 }
 
 uae_u8 *save_zram (int *len, int num)
@@ -1545,10 +1783,21 @@ uae_u8 *save_pram (int *len)
        return gfxmem_bank.baseaddr;
 }
 
-void restore_fram (int len, size_t filepos)
+void restore_fram (int len, size_t filepos, int num)
 {
-       fast_filepos = filepos;
-       changed_prefs.fastmem_size = len;
+       if (num) {
+               fast2_filepos = filepos;
+               changed_prefs.fastmem2_size = len;
+       } else {
+               fast_filepos = filepos;
+               changed_prefs.fastmem_size = len;
+       }
+}
+
+void restore_fram2 (int len, size_t filepos)
+{
+       fast2_filepos = filepos;
+       changed_prefs.fastmem2_size = len;
 }
 
 void restore_zram (int len, size_t filepos, int num)
@@ -1573,15 +1822,17 @@ void restore_pram (int len, size_t filepos)
 
 uae_u8 *save_expansion (int *len, uae_u8 *dstptr)
 {
-       static uae_u8 t[20];
-       uae_u8 *dst = t, *dstbak = t;
+       uae_u8 *dst, *dstbak;
        if (dstptr)
                dst = dstbak = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 6 * 4);
        save_u32 (fastmem_bank.start);
        save_u32 (z3fastmem_bank.start);
        save_u32 (gfxmem_bank.start);
        save_u32 (rtarea_base);
-       *len = 4 + 4 + 4 + 4;
+       save_u32 (fastmem_bank.start);
+       *len = 4 + 4 + 4 + 4 + 4;
        return dstbak;
 }
 
@@ -1591,6 +1842,7 @@ uae_u8 *restore_expansion (uae_u8 *src)
        z3fastmem_bank.start = restore_u32 ();
        gfxmem_bank.start = restore_u32 ();
        rtarea_base = restore_u32 ();
+       fastmem2_bank.start = restore_u32 ();
        if (rtarea_base != 0 && rtarea_base != RTAREA_DEFAULT && rtarea_base != RTAREA_BACKUP)
                rtarea_base = 0;
        return src;
index 536481ed12ad94eb7af0103428f83da43aee22a0..49dc65c5e28233c3536e2ede5fb444ecc862d30e 100644 (file)
@@ -158,7 +158,8 @@ typedef struct {
        bool unknown_media; /* ID_UNREADABLE_DISK */
        int bootpri; /* boot priority. -128 = no autoboot, -129 = no mount */
        int devno;
-       int controller;
+       int controller_type;
+       int controller_unit;
        bool wasisempty; /* if true, this unit was created empty */
        bool canremove; /* if true, this unit can be safely ejected and remounted */
        bool configureddrive; /* if true, this is drive that was manually configured */
@@ -213,12 +214,12 @@ int nr_directory_units (struct uae_prefs *p)
        int i, cnt = 0;
        if (p) {
                for (i = 0; i < p->mountitems; i++) {
-                       if (p->mountconfig[i].ci.controller == 0)
+                       if (p->mountconfig[i].ci.controller_type == HD_CONTROLLER_TYPE_UAE)
                                cnt++;
                }
        } else {
                for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
-                       if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller == 0)
+                       if (mountinfo.ui[i].open > 0 && mountinfo.ui[i].controller_type == HD_CONTROLLER_TYPE_UAE)
                                cnt++;
                }
        }
@@ -358,7 +359,7 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo *
 #endif
                }
        } else if (uci->ci.type != UAEDEV_TAPE) {
-               if (!ui->controller || (ui->controller && p->cs_ide)) {
+               if (ui->controller_type == HD_CONTROLLER_TYPE_UAE) { // what is this? || (ui->controller && p->cs_ide)) {
                        mi->ismounted = 1;
                        if (uci->ci.type == UAEDEV_HDF)
                                mi->ismedia = ui->hf.drive_empty ? false : true;
@@ -580,7 +581,7 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                }
        }
 
-       if (ci->controller || ci->type == UAEDEV_TAPE) {
+       if (ci->controller_type != HD_CONTROLLER_TYPE_UAE || ci->type == UAEDEV_TAPE) {
                ui = &mountinfo.ui[nr];
                memset (ui, 0, sizeof (UnitInfo));
                memcpy (&ui->hf.ci, &c, sizeof (struct uaedev_config_info));
@@ -721,7 +722,7 @@ int kill_filesys_unitconfig (struct uae_prefs *p, int nr)
                return 0;
        uci = getuci (p->mountconfig, nr);
        hardfile_do_disk_change (uci, 0);
-       if (uci->configoffset >= 0 && uci->ci.controller == 0)
+       if (uci->configoffset >= 0 && uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE)
                filesys_media_change (uci->ci.rootdir, 0, uci);
        while (nr < MOUNT_CONFIG_SIZE) {
                memmove (&p->mountconfig[nr], &p->mountconfig[nr + 1], sizeof (struct uaedev_config_data));
@@ -777,7 +778,7 @@ static void initialize_mountinfo (void)
 
        for (nr = 0; nr < currprefs.mountitems; nr++) {
                struct uaedev_config_data *uci = &currprefs.mountconfig[nr];
-               if (uci->ci.controller == HD_CONTROLLER_UAE && (uci->ci.type == UAEDEV_DIR || uci->ci.type == UAEDEV_HDF)) {
+               if (uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE && (uci->ci.type == UAEDEV_DIR || uci->ci.type == UAEDEV_HDF)) {
                        struct uaedev_config_info ci;
                        memcpy (&ci, &uci->ci, sizeof (struct uaedev_config_info));
                        ci.flags = MYVOLUMEINFO_REUSABLE;
@@ -810,7 +811,7 @@ static void initialize_mountinfo (void)
 
        for (nr = 0; nr < currprefs.mountitems; nr++) {
                struct uaedev_config_data *uci = &currprefs.mountconfig[nr];
-               if (uci->ci.controller == HD_CONTROLLER_UAE) {
+               if (uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE) {
                        if (uci->ci.type == UAEDEV_TAPE) {
                                struct uaedev_config_info ci;
                                memcpy (&ci, &uci->ci, sizeof (struct uaedev_config_info));
@@ -825,51 +826,104 @@ static void initialize_mountinfo (void)
 
        for (nr = 0; nr < currprefs.mountitems; nr++) {
                struct uaedev_config_info *uci = &currprefs.mountconfig[nr].ci;
-               if (uci->controller == HD_CONTROLLER_UAE) {
+               int type = uci->controller_type;
+               int unit = uci->controller_unit;
+               bool added = false;
+               if (type == HD_CONTROLLER_TYPE_UAE) {
                        continue;
-               } else if (uci->controller <= HD_CONTROLLER_IDE3) {
-                       gayle_add_ide_unit (uci->controller - HD_CONTROLLER_IDE0, uci);
-                       allocuci (&currprefs, nr, -1);
-               } else if (uci->controller <= HD_CONTROLLER_SCSI6) {
+               } else if (type >= HD_CONTROLLER_TYPE_IDE_FIRST && type <= HD_CONTROLLER_TYPE_IDE_LAST) {
+                       gayle_add_ide_unit (unit, uci);
+                       added = true;
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A2091) {
+#ifdef A2091
+                       if (currprefs.a2091) {
+                               a2091_add_scsi_unit (unit, uci, 0);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A2091_2) {
+#ifdef A2091
+                       if (currprefs.a2091) {
+                               a2091_add_scsi_unit (unit, uci, 1);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A3000) {
+#ifdef A2091
+                       if (currprefs.cs_mbdmac == 1) {
+                               a3000_add_scsi_unit (unit, uci);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A4091) {
+#ifdef NCR
+                       if (currprefs.a4091) {
+                               a4091_add_scsi_unit (unit, uci, 0);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A4091_2) {
+#ifdef NCR
+                       if (currprefs.a4091) {
+                               a4091_add_scsi_unit (unit, uci, 1);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_A4000T) {
+#ifdef NCR
+                       if (currprefs.cs_mbdmac == 2) {
+                               a4000t_add_scsi_unit (unit, uci);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_CDTV) {
+#ifdef CDTV
+                       if (currprefs.cs_cdtvscsi) {
+                               cdtv_add_scsi_hd_unit (unit, uci);
+                               added = true;
+                       }
+#endif
+               } else if (type == HD_CONTROLLER_TYPE_SCSI_AUTO) {
                        if (currprefs.cs_mbdmac == 1) {
 #ifdef A2091
-                               a3000_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
-                               allocuci (&currprefs, nr, -1);
+                               a3000_add_scsi_unit (unit, uci);
+                               added = true;
 #endif
                        } else if (currprefs.cs_mbdmac == 2) {
 #ifdef NCR
-                               a4000t_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);      
-                               allocuci (&currprefs, nr, -1);
+                               a4000t_add_scsi_unit (unit, uci);       
+                               added = true;
 #endif
                        } else if (currprefs.a2091) {
 #ifdef A2091
-                               a2091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
-                               allocuci (&currprefs, nr, -1);
+                               a2091_add_scsi_unit (unit, uci, 0);
+                               added = true;
 #endif
                        } else if (currprefs.a4091) {
 #ifdef NCR
-                               a4091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
-                               allocuci (&currprefs, nr, -1);
+                               a4091_add_scsi_unit (unit, uci, 0);
+                               added = true;
 #endif
                        } else if (currprefs.cs_cdtvscsi) {
 #ifdef CDTV
-                               cdtv_add_scsi_hd_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
-                               allocuci (&currprefs, nr, -1);
+                               cdtv_add_scsi_hd_unit (unit, uci);
+                               added = true;
 #endif
                        }
-               } else if (uci->controller == HD_CONTROLLER_PCMCIA_SRAM) {
+               } else if (type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
                        gayle_add_pcmcia_sram_unit (uci->rootdir, uci->readonly);
-                       allocuci (&currprefs, nr, -1);
-               } else if (uci->controller == HD_CONTROLLER_PCMCIA_IDE) {
+                       added = true;
+               } else if (type == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
                        gayle_add_pcmcia_ide_unit (uci->rootdir, uci->readonly);
-                       allocuci (&currprefs, nr, -1);
+                       added = true;
                }
+               if (added)
+                       allocuci (&currprefs, nr, -1);
        }
        
 
 }
 
-
 int sprintf_filesys_unit (TCHAR *buffer, int num)
 {
        UnitInfo *uip = mountinfo.ui;
@@ -3635,13 +3689,15 @@ static ExamineKey *new_exkey (Unit *unit, a_inode *aino)
        ek = oldest_ek;
 found:
 
-       uniq = unit->next_exkey;
+       uniq = aino->uniq;
+#if 0
        if (uniq >= 0xFFFFFFFE) {
                /* Things will probably go wrong, but most likely the Amiga will crash
                * before this happens because of something else. */
                uniq = 1;
        }
        unit->next_exkey = uniq + 1;
+#endif
        ek->aino = aino;
        ek->curr_file = 0;
        ek->uniq = uniq;
@@ -3700,6 +3756,7 @@ static void
                return;
        }
 
+       put_long(info + 0, aino->uniq);
        if (aino->parent == 0) {
                /* Guru book says ST_ROOT = 1 (root directory, not currently used)
                * but some programs really expect 2 from root dir..
@@ -4387,10 +4444,6 @@ static void action_examine_object (Unit *unit, dpacket packet)
                aino = &unit->rootnode;
 
        get_fileinfo (unit, packet, info, aino, false);
-       if (aino->dir) {
-               put_long (info, 0xFFFFFFFF);
-       } else
-               put_long (info, 0);
 }
 
 /* Read a directory's contents, create a_inodes for each file, and
@@ -4482,30 +4535,34 @@ static void action_examine_next (Unit *unit, dpacket packet, bool largefilesize)
                aino = &unit->rootnode;
        for(;;) {
                uniq = get_long (info);
-               if (uniq == 0) {
-                       write_log (_T("ExNext called for a file! (Houston?)\n"));
-                       goto no_more_entries;
-               } else if (uniq == 0xFFFFFFFE)
-                       goto no_more_entries;
-               else if (uniq == 0xFFFFFFFF) {
+               if (uniq == aino->uniq) {
+                       // first exnext
+                       if (!aino->dir) {
+                               write_log (_T("ExNext called for a file! (Houston?)\n"));
+                               goto no_more_entries;
+                       }
                        TRACE((_T("Creating new ExKey\n")));
                        ek = new_exkey (unit, aino);
                        if (ek) {
                                if (aino->exnext_count++ == 0)
                                        populate_directory (unit, aino);
+                               if (!aino->child) {
+                                       free_exkey (unit, ek);
+                                       goto no_more_entries;
+                               }
                                ek->curr_file = aino->child;
                                TRACE((_T("Initial curr_file: %p %s\n"), ek->curr_file,
                                        ek->curr_file ? ek->curr_file->aname : _T("NULL")));
+                               uniq = ek->curr_file->uniq;
                        }
                } else {
                        TRACE((_T("Looking up ExKey\n")));
-                       ek = lookup_exkey (unit, get_long (info));
+                       ek = lookup_exkey(unit, aino->uniq);
                }
                if (ek == 0) {
                        write_log (_T("Couldn't find a matching ExKey. Prepare for trouble.\n"));
                        goto no_more_entries;
                }
-               put_long (info, ek->uniq);
                if (!ek->curr_file || ek->curr_file->mountcount == unit->mountcount)
                        break;
                ek->curr_file = ek->curr_file->sibling;
@@ -5303,10 +5360,6 @@ static void
                aino = &unit->rootnode;
 
        get_fileinfo (unit, packet, info, aino, largefilesize);
-       if (aino->dir)
-               put_long (info, 0xFFFFFFFF);
-       else
-               put_long (info, 0);
 }
 
 /* For a nice example of just how contradictory documentation can be, see the
@@ -5883,10 +5936,6 @@ static void action_examine_object64(Unit *unit, dpacket packet)
                aino = &unit->rootnode;
 
        get_fileinfo (unit, packet, info, aino, true);
-       if (aino->dir) {
-               put_long (info, 0xFFFFFFFF);
-       } else
-               put_long (info, 0);
 }
 
 static void action_set_file_size64(Unit *unit, dpacket packet)
@@ -6918,6 +6967,7 @@ static void dump_partinfo (struct hardfiledata *hfd, uae_u8 *pp)
                spt, reserved, lowcyl, highcyl, (uae_u32)(size >> 20));
        write_log (_T("Buffers: %d, BufMemType: %08x, MaxTransfer: %08x, Mask: %08x, BootPri: %d\n"),
                rl (pp + 44), rl (pp + 48), rl (pp + 52), rl (pp + 56), rl (pp + 60));
+       write_log (_T("Total blocks: %d, Total disk blocks: %d\n"), surfaces * spt * (highcyl - lowcyl + 1), hfd->virtsize / blocksize);
 
        if (hfd->drive_empty) {
                write_log (_T("Empty drive\n"));
index 850930da1081130909382c8c5ddf2115e80f67a6..a8ca55f817637521619832a241ed7045a9da86ef 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
 #include "savestate.h"
 #include "uae.h"
 #include "gui.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "ncr_scsi.h"
 #include "blkdev.h"
 #include "scsi.h"
-#include "threaddep/thread.h"
 
 #define PCMCIA_SRAM 1
 #define PCMCIA_IDE 2
@@ -1557,12 +1557,12 @@ static uae_u32 REGPARAM2 gayle_lget (uaecptr addr)
        if (isa4000t (&addr)) {
                if (addr >= NCR_ALT_OFFSET) {
                        addr &= NCR_MASK;
-                       v = (ncr_io_bget (addr + 3) << 0) | (ncr_io_bget (addr + 2) << 8) |
-                               (ncr_io_bget (addr + 1) << 16) | (ncr_io_bget (addr + 0) << 24);
+                       v = (ncr_io_bget_a4000t (addr + 3) << 0) | (ncr_io_bget_a4000t (addr + 2) << 8) |
+                               (ncr_io_bget_a4000t (addr + 1) << 16) | (ncr_io_bget_a4000t (addr + 0) << 24);
                } else if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       v = (ncr_io_bget (addr + 3) << 0) | (ncr_io_bget (addr + 2) << 8) |
-                               (ncr_io_bget (addr + 1) << 16) | (ncr_io_bget (addr + 0) << 24);
+                       v = (ncr_io_bget_a4000t (addr + 3) << 0) | (ncr_io_bget_a4000t (addr + 2) << 8) |
+                               (ncr_io_bget_a4000t (addr + 1) << 16) | (ncr_io_bget_a4000t (addr + 0) << 24);
                }
                return v;
        }
@@ -1591,7 +1591,7 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr)
        if (isa4000t (&addr)) {
                if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       v = (ncr_io_bget (addr) << 8) | ncr_io_bget (addr + 1);
+                       v = (ncr_io_bget_a4000t (addr) << 8) | ncr_io_bget_a4000t (addr + 1);
                }
                return v;
        }
@@ -1614,7 +1614,7 @@ static uae_u32 REGPARAM2 gayle_bget (uaecptr addr)
        if (isa4000t (&addr)) {
                if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       return ncr_io_bget (addr);
+                       return ncr_io_bget_a4000t (addr);
                }
                return 0;
        }
@@ -1632,16 +1632,16 @@ static void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value)
        if (isa4000t (&addr)) {
                if (addr >= NCR_ALT_OFFSET) {
                        addr &= NCR_MASK;
-                       ncr_io_bput (addr + 3, value >> 0);
-                       ncr_io_bput (addr + 2, value >> 8);
-                       ncr_io_bput (addr + 1, value >> 16);
-                       ncr_io_bput (addr + 0, value >> 24);
+                       ncr_io_bput_a4000t (addr + 3, value >> 0);
+                       ncr_io_bput_a4000t (addr + 2, value >> 8);
+                       ncr_io_bput_a4000t (addr + 1, value >> 16);
+                       ncr_io_bput_a4000t (addr + 0, value >> 24);
                } else if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       ncr_io_bput (addr + 3, value >> 0);
-                       ncr_io_bput (addr + 2, value >> 8);
-                       ncr_io_bput (addr + 1, value >> 16);
-                       ncr_io_bput (addr + 0, value >> 24);
+                       ncr_io_bput_a4000t (addr + 3, value >> 0);
+                       ncr_io_bput_a4000t (addr + 2, value >> 8);
+                       ncr_io_bput_a4000t (addr + 1, value >> 16);
+                       ncr_io_bput_a4000t (addr + 0, value >> 24);
                }
                return;
        }
@@ -1665,8 +1665,8 @@ static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value)
        if (isa4000t (&addr)) {
                if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       ncr_io_bput (addr, value >> 8);
-                       ncr_io_bput (addr + 1, value);
+                       ncr_io_bput_a4000t (addr, value >> 8);
+                       ncr_io_bput_a4000t (addr + 1, value);
                }
                return;
        }
@@ -1689,7 +1689,7 @@ static void REGPARAM2 gayle_bput (uaecptr addr, uae_u32 value)
        if (isa4000t (&addr)) {
                if (addr >= NCR_OFFSET) {
                        addr &= NCR_MASK;
-                       ncr_io_bput (addr, value);
+                       ncr_io_bput_a4000t (addr, value);
                }
                return;
        }
index 7608e75627bf563aed1b1b3b0322249c53c72d85..76942a7f39144af970eb2d9073ab837bcb67db8c 100644 (file)
@@ -3526,6 +3526,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\t\tint frame = format >> 12;\n");
                        printf ("\t\tint offset = 8;\n");
                        printf ("\t\tnewsr = sr; newpc = pc;\n");
+                       addcycles_ce020 (6);
                    printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n");
                    printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n");
                    printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n");
@@ -3554,6 +3555,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("}\n");
                    pop_braces (old_brace_level);
                    printf ("\tregs.sr = newsr;\n");
+                       addcycles_ce020 (4);
                        makefromsr ();
                    printf ("\tif (newpc & 1) {\n");
                    printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
index 943efc2501fae330bce715dde5bc1df7794d1809..4b244496781da79ce08a2b2257870178cc198b82 100644 (file)
@@ -168,8 +168,9 @@ static void getchsgeometry2 (uae_u64 size, int *pcyl, int *phead, int *psectorsp
                sptt[3] = -1;
 
                for (i = 0; sptt[i] >= 0; i++) {
+                       int maxhead = sptt[i] < 255 ? 16 : 255;
                        spt = sptt[i];
-                       for (head = 4; head <= 16;head++) {
+                       for (head = 4; head <= maxhead; head++) {
                                cyl = total / (head * spt);
                                if (size <= 512 * 1024 * 1024) {
                                        if (cyl <= 1023)
@@ -182,12 +183,18 @@ static void getchsgeometry2 (uae_u64 size, int *pcyl, int *phead, int *psectorsp
                                        if (cyl <= 65535)
                                                break;
                                }
+                               if (maxhead > 16) {
+                                       head *= 2;
+                                       head--;
+                               }
                        }
                        if (head <= 16)
                                break;
                }
 
        }
+       if (head > 16)
+               head--;
 
        *pcyl = cyl;
        *phead = head;
@@ -1587,10 +1594,10 @@ void hardfile_do_disk_change (struct uaedev_config_data *uci, bool insert)
        int fsid = uci->configoffset;
        struct hardfiledata *hfd;
 
-       if (uci->ci.controller == HD_CONTROLLER_PCMCIA_SRAM) {
+       if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
                gayle_modify_pcmcia_sram_unit (uci->ci.rootdir, uci->ci.readonly, insert);
                return;
-       } else if (uci->ci.controller == HD_CONTROLLER_PCMCIA_IDE) {
+       } else if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
                gayle_modify_pcmcia_ide_unit (uci->ci.rootdir, uci->ci.readonly, insert);
                return;
        }
index a060ff686e8a8a42b774f199d5d50fd434ff3721..394d6acfa028107d42041693e149be0f511687e8 100644 (file)
@@ -4,13 +4,54 @@
 
 #ifdef A2091
 
-extern addrbank dmaca2091_bank;
+#define WD_STATUS_QUEUE 2
 
-extern void init_scsi (void);
-extern void scsi_dmac_start_dma (void);
-extern void scsi_dmac_stop_dma (void);
+struct wd_state {
+       bool enabled;
+       TCHAR *name;
+       int configured;
+       bool autoconfig;
+       uae_u8 dmacmemory[100];
+       uae_u8 *rom;
+       int rombankswitcher, rombank;
+       int rom_size, rom_mask;
 
-extern void a2091_init (void);
+       uae_u32 dmac_istr, dmac_cntr;
+       uae_u32 dmac_dawr;
+       uae_u32 dmac_acr;
+       uae_u32 dmac_wtc;
+       int dmac_dma;
+       volatile uae_u8 sasr, scmd, auxstatus;
+       volatile int wd_used;
+       volatile int wd_phase, wd_next_phase, wd_busy, wd_data_avail;
+       volatile bool wd_selected;
+       volatile int wd_dataoffset;
+       volatile uae_u8 wd_data[32];
+
+       volatile int scsidelay_irq[WD_STATUS_QUEUE];
+       volatile uae_u8 scsidelay_status[WD_STATUS_QUEUE];
+       volatile int queue_index;
+       smp_comm_pipe requests;
+       volatile int scsi_thread_running;
+
+       int old_dmac;
+       int superdmac;
+       int wd33c93_ver;// 0 or 1
+
+       struct scsi_data *scsis[8];
+       struct scsi_data *scsi;
+
+       uae_u8 wdregs[32];
+
+       bool cdtv;
+};
+extern wd_state wd_cdtv;
+
+extern void init_scsi (struct wd_state*);
+extern void scsi_dmac_start_dma (struct wd_state*);
+extern void scsi_dmac_stop_dma (struct wd_state*);
+
+extern void a2091_init (int devnum);
 extern void a2091_free (void);
 extern void a2091_reset (void);
 
@@ -19,24 +60,27 @@ extern void a3000scsi_free (void);
 extern void a3000scsi_reset (void);
 extern void rethink_a2091 (void);
 
-extern void wdscsi_put (uae_u8);
-extern uae_u8 wdscsi_get (void);
-extern uae_u8 wdscsi_getauxstatus (void);
-extern void wdscsi_sasr (uae_u8);
+extern void wdscsi_put (struct wd_state*, uae_u8);
+extern uae_u8 wdscsi_get (struct wd_state*);
+extern uae_u8 wdscsi_getauxstatus (struct wd_state*);
+extern void wdscsi_sasr (struct wd_state*, uae_u8);
 
 extern void scsi_hsync (void);
 
-extern uae_u8 wdregs[32];
-extern struct scsi_data *scsis[8];
+#define WDTYPE_A2091 0
+#define WDTYPE_A2091_2 1
+#define WDTYPE_A3000 2
+#define WDTYPE_CDTV 3
 
 #define WD33C93 _T("WD33C93")
 
-extern int a2091_add_scsi_unit (int ch, struct uaedev_config_info *ci);
+extern int a2091_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum);
 extern int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci);
 
-extern int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
-extern int add_scsi_cd (int ch, int unitnum);
-extern int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly);
+
+extern int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
+extern int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum);
+extern int add_wd_scsi_tape (struct wd_state *wd, int ch, const TCHAR *tape_directory, bool readonly);
 
 #endif
 
index 3e65ad43e1bd82124a8ff69a5dd5f852e669c887..d09d5846ccb834ebdb4d7574e1ffcb840581fa6e 100644 (file)
@@ -10,6 +10,11 @@ typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ES
 
 #define HISTORY_FLOPPY 0
 #define HISTORY_CD 1
+#define HISTORY_DIR 2
+#define HISTORY_HDF 3
+#define HISTORY_FS 4
+#define HISTORY_TAPE 5
+#define HISTORY_MAX 6
 
 struct diskinfo
 {
@@ -69,5 +74,5 @@ extern int disk_debug_track;
 #define DISK_DEBUG_DMA_WRITE 2
 #define DISK_DEBUG_PIO 4
 
-#define MAX_PREVIOUS_FLOPPIES 99
+#define MAX_PREVIOUS_IMAGES 50
 
index bdf625c910377b696fafbfbd6598628a0b8df631..1327d80bdfbf9ccf26dd39429b60f35ae7b9a509 100644 (file)
@@ -88,20 +88,24 @@ struct hd_hardfiledata {
     int ansi_version;
 };
 
-#define HD_CONTROLLER_UAE 0
-#define HD_CONTROLLER_IDE0 1
-#define HD_CONTROLLER_IDE1 2
-#define HD_CONTROLLER_IDE2 3
-#define HD_CONTROLLER_IDE3 4
-#define HD_CONTROLLER_SCSI0 5
-#define HD_CONTROLLER_SCSI1 6
-#define HD_CONTROLLER_SCSI2 7
-#define HD_CONTROLLER_SCSI3 8
-#define HD_CONTROLLER_SCSI4 9
-#define HD_CONTROLLER_SCSI5 10
-#define HD_CONTROLLER_SCSI6 11
-#define HD_CONTROLLER_PCMCIA_SRAM 12
-#define HD_CONTROLLER_PCMCIA_IDE 13
+#define HD_CONTROLLER_TYPE_UAE 0
+#define HD_CONTROLLER_TYPE_IDE_AUTO 1
+#define HD_CONTROLLER_TYPE_IDE_MB 1
+#define HD_CONTROLLER_TYPE_SCSI_AUTO 2
+#define HD_CONTROLLER_TYPE_SCSI_A2091 3
+#define HD_CONTROLLER_TYPE_SCSI_A2091_2 4
+#define HD_CONTROLLER_TYPE_SCSI_A4091 5
+#define HD_CONTROLLER_TYPE_SCSI_A4091_2 6
+#define HD_CONTROLLER_TYPE_SCSI_A3000 7
+#define HD_CONTROLLER_TYPE_SCSI_A4000T 8
+#define HD_CONTROLLER_TYPE_SCSI_CDTV 9
+#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 10
+#define HD_CONTROLLER_TYPE_PCMCIA_IDE 11
+
+#define HD_CONTROLLER_TYPE_IDE_FIRST 1
+#define HD_CONTROLLER_TYPE_IDE_LAST 1
+#define HD_CONTROLLER_TYPE_SCSI_FIRST 2
+#define HD_CONTROLLER_TYPE_SCSI_LAST 9
 
 #define FILESYS_VIRTUAL 0
 #define FILESYS_HARDFILE 1
index 4abc48b5340b5abc49ab229440f4ce19c16aea99..adb144e1a4714307922b5660934d358aed6d8168 100644 (file)
@@ -164,6 +164,7 @@ extern bool my_resolvessymboliclink(TCHAR *linkfile, int size);
 extern bool my_resolvesoftlink(TCHAR *linkfile, int size);
 extern void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size);
 extern int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path);
+extern bool my_issamepath(const TCHAR *path1, const TCHAR *path2);
 extern bool my_createsoftlink(const TCHAR *path, const TCHAR *target);
 extern bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description);
 
index 6694746671d73c4a6a99c394524f2fb3f7db940a..d0aa3e556ad3977f854881fa66e21dd1a6b95337 100644 (file)
@@ -106,58 +106,65 @@ typedef struct {
 #define CE_MEMBANK_FAST16 4
 extern uae_u8 ce_banktype[65536], ce_cachable[65536];
 
-#define MEMORY_LGET(name) \
+#ifdef JIT
+#define MEMORY_LGET(name, nojit) \
 static uae_u32 REGPARAM3 name ## _lget (uaecptr) REGPARAM; \
 static uae_u32 REGPARAM2 name ## _lget (uaecptr addr) \
 { \
        uae_u8 *m; \
+       if (nojit) special_mem |= S_READ; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        m = name ## _bank.baseaddr + addr; \
        return do_get_mem_long ((uae_u32 *)m); \
 }
-#define MEMORY_WGET(name) \
+#define MEMORY_WGET(name, nojit) \
 static uae_u32 REGPARAM3 name ## _wget (uaecptr) REGPARAM; \
 static uae_u32 REGPARAM2 name ## _wget (uaecptr addr) \
 { \
        uae_u8 *m; \
+       if (nojit) special_mem |= S_READ; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        m = name ## _bank.baseaddr + addr; \
        return do_get_mem_word ((uae_u16 *)m); \
 }
-#define MEMORY_BGET(name) \
+#define MEMORY_BGET(name, nojit) \
 static uae_u32 REGPARAM3 name ## _bget (uaecptr) REGPARAM; \
 static uae_u32 REGPARAM2 name ## _bget (uaecptr addr) \
 { \
+       if (nojit) special_mem |= S_READ; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        return name ## _bank.baseaddr[addr]; \
 }
-#define MEMORY_LPUT(name) \
+#define MEMORY_LPUT(name, nojit) \
 static void REGPARAM3 name ## _lput (uaecptr, uae_u32) REGPARAM; \
 static void REGPARAM2 name ## _lput (uaecptr addr, uae_u32 l) \
 { \
        uae_u8 *m;  \
+       if (nojit) special_mem |= S_WRITE; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        m = name ## _bank.baseaddr + addr; \
        do_put_mem_long ((uae_u32 *)m, l); \
 }
-#define MEMORY_WPUT(name) \
+#define MEMORY_WPUT(name, nojit) \
 static void REGPARAM3 name ## _wput (uaecptr, uae_u32) REGPARAM; \
 static void REGPARAM2 name ## _wput (uaecptr addr, uae_u32 w) \
 { \
        uae_u8 *m;  \
+       if (nojit) special_mem |= S_WRITE; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        m = name ## _bank.baseaddr + addr; \
        do_put_mem_word ((uae_u16 *)m, w); \
 }
-#define MEMORY_BPUT(name) \
+#define MEMORY_BPUT(name, nojit) \
 static void REGPARAM3 name ## _bput (uaecptr, uae_u32) REGPARAM; \
 static void REGPARAM2 name ## _bput (uaecptr addr, uae_u32 b) \
 { \
+       if (nojit) special_mem |= S_WRITE; \
        addr -= name ## _bank.start & name ## _bank.mask; \
        addr &= name ## _bank.mask; \
        name ## _bank.baseaddr[addr] = b; \
@@ -178,14 +185,97 @@ static uae_u8 *REGPARAM2 name ## _xlate (uaecptr addr) \
        addr &= name ## _bank.mask; \
        return name ## _bank.baseaddr + addr; \
 }
+#else
+#define MEMORY_LGET(name, nojit) \
+static uae_u32 REGPARAM3 name ## _lget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## _lget (uaecptr addr) \
+{ \
+       uae_u8 *m; \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       m = name ## _bank.baseaddr + addr; \
+       return do_get_mem_long ((uae_u32 *)m); \
+}
+#define MEMORY_WGET(name, nojit) \
+static uae_u32 REGPARAM3 name ## _wget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## _wget (uaecptr addr) \
+{ \
+       uae_u8 *m; \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       m = name ## _bank.baseaddr + addr; \
+       return do_get_mem_word ((uae_u16 *)m); \
+}
+#define MEMORY_BGET(name, nojit) \
+static uae_u32 REGPARAM3 name ## _bget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## _bget (uaecptr addr) \
+{ \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       return name ## _bank.baseaddr[addr]; \
+}
+#define MEMORY_LPUT(name, nojit) \
+static void REGPARAM3 name ## _lput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## _lput (uaecptr addr, uae_u32 l) \
+{ \
+       uae_u8 *m;  \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       m = name ## _bank.baseaddr + addr; \
+       do_put_mem_long ((uae_u32 *)m, l); \
+}
+#define MEMORY_WPUT(name, nojit) \
+static void REGPARAM3 name ## _wput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## _wput (uaecptr addr, uae_u32 w) \
+{ \
+       uae_u8 *m;  \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       m = name ## _bank.baseaddr + addr; \
+       do_put_mem_word ((uae_u16 *)m, w); \
+}
+#define MEMORY_BPUT(name, nojit) \
+static void REGPARAM3 name ## _bput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## _bput (uaecptr addr, uae_u32 b) \
+{ \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       name ## _bank.baseaddr[addr] = b; \
+}
+#define MEMORY_CHECK(name) \
+static int REGPARAM3 name ## _check (uaecptr addr, uae_u32 size) REGPARAM; \
+static int REGPARAM2 name ## _check (uaecptr addr, uae_u32 size) \
+{ \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       return (addr + size) <= name ## _bank.allocated; \
+}
+#define MEMORY_XLATE(name) \
+static uae_u8 *REGPARAM3 name ## _xlate (uaecptr addr) REGPARAM; \
+static uae_u8 *REGPARAM2 name ## _xlate (uaecptr addr) \
+{ \
+       addr -= name ## _bank.start & name ## _bank.mask; \
+       addr &= name ## _bank.mask; \
+       return name ## _bank.baseaddr + addr; \
+}
+#endif
 
 #define MEMORY_FUNCTIONS(name) \
-MEMORY_LGET(name); \
-MEMORY_WGET(name); \
-MEMORY_BGET(name); \
-MEMORY_LPUT(name); \
-MEMORY_WPUT(name); \
-MEMORY_BPUT(name); \
+MEMORY_LGET(name, 0); \
+MEMORY_WGET(name, 0); \
+MEMORY_BGET(name, 0); \
+MEMORY_LPUT(name, 0); \
+MEMORY_WPUT(name, 0); \
+MEMORY_BPUT(name, 0); \
+MEMORY_CHECK(name); \
+MEMORY_XLATE(name);
+#define MEMORY_FUNCTIONS_NOJIT(name) \
+MEMORY_LGET(name, 1); \
+MEMORY_WGET(name, 1); \
+MEMORY_BGET(name, 1); \
+MEMORY_LPUT(name, 1); \
+MEMORY_WPUT(name, 1); \
+MEMORY_BPUT(name, 1); \
 MEMORY_CHECK(name); \
 MEMORY_XLATE(name);
 
@@ -202,6 +292,9 @@ extern addrbank cia_bank;
 extern addrbank rtarea_bank;
 extern addrbank expamem_bank;
 extern addrbank fastmem_bank;
+extern addrbank fastmem_nojit_bank;
+extern addrbank fastmem2_bank;
+extern addrbank fastmem2_nojit_bank;
 extern addrbank gfxmem_bank;
 extern addrbank gayle_bank;
 extern addrbank gayle2_bank;
@@ -270,7 +363,7 @@ extern void map_banks_cond (addrbank *bank, int first, int count, int realsize);
 extern void map_overlay (int chip);
 extern void memory_hardreset (int);
 extern void memory_clear (void);
-extern void free_fastmemory (void);
+extern void free_fastmemory (int);
 
 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
index f258f813e022c74f2e44f619096ac52c613ab23e..0c4b49841065be273667e7bedfd69bef3c6c8a80 100644 (file)
@@ -1,11 +1,11 @@
 
-void ncr_io_bput(uaecptr, uae_u32);
-uae_u32 ncr_io_bget(uaecptr);
+void ncr_io_bput_a4000t(uaecptr, uae_u32);
+uae_u32 ncr_io_bget_a4000t(uaecptr);
 
 extern void ncr_init(void);
-extern void ncr_autoconfig_init(void);
+extern void ncr_autoconfig_init(int devnum);
 extern void ncr_free(void);
 extern void ncr_reset(void);
 
 extern int a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci);
-extern int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci);
+extern int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum);
index fc04c8d5fb66705063cc0e6721055b0f37326c7f..a8ce1e5fdf49bc8a13f6dfa736c668ba569ee207 100644 (file)
@@ -12,7 +12,7 @@
 
 #define UAEMAJOR 2
 #define UAEMINOR 8
-#define UAESUBREV 1
+#define UAESUBREV 2
 
 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
 
@@ -149,7 +149,8 @@ struct uaedev_config_info {
        int sectors;
        int reserved;
        int blocksize;
-       int controller;
+       int controller_type;
+       int controller_unit;
        // zero if default
        int pcyls, pheads, psecs;
        int flags;
@@ -438,6 +439,7 @@ struct uae_prefs {
        bool cs_dipagnus;
        bool cs_agnusbltbusybug;
        bool cs_ciatodbug;
+       bool cs_z3autoconfig;
        int cs_hacks;
 
        TCHAR romfile[MAX_DPATH];
@@ -448,9 +450,13 @@ struct uae_prefs {
        TCHAR romextident[256];
        TCHAR a2091romfile[MAX_DPATH];
        TCHAR a2091romident[256];
+       TCHAR a2091romfile2[MAX_DPATH];
+       TCHAR a2091romident2[256];
        bool a2091;
        TCHAR a4091romfile[MAX_DPATH];
        TCHAR a4091romident[256];
+       TCHAR a4091romfile2[MAX_DPATH];
+       TCHAR a4091romident2[256];
        bool a4091;
        TCHAR flashfile[MAX_DPATH];
        TCHAR rtcfile[MAX_DPATH];
@@ -514,6 +520,7 @@ struct uae_prefs {
        bool native_code;
        bool uae_hide_autoconfig;
        bool jit_direct_compatible_memory;
+       bool force_0x10000000_z3;
 
        int mountitems;
        struct uaedev_config_data mountconfig[MOUNT_CONFIG_SIZE];
index bfd43cf2890c7df0738f0bf7b2c0e833bd16c0f7..800c48f8983e69b592e912af710f1e737921e4d0 100644 (file)
@@ -135,11 +135,11 @@ extern void restore_cdtv_finish (void);
 
 extern uae_u8 *restore_cdtv_dmac (uae_u8 *src);
 extern uae_u8 *save_cdtv_dmac (int *len, uae_u8*);
-extern uae_u8 *restore_scsi_dmac (uae_u8 *src);
-extern uae_u8 *save_scsi_dmac (int *len, uae_u8*);
+extern uae_u8 *restore_scsi_dmac (int wdtype, uae_u8 *src);
+extern uae_u8 *save_scsi_dmac (int wdtype, int *len, uae_u8*);
 
-extern uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr);
-extern uae_u8 *restore_scsi_device (uae_u8 *src);
+extern uae_u8 *save_scsi_device (int wdtype, int num, int *len, uae_u8 *dstptr);
+extern uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src);
 
 extern uae_u8 *save_scsidev (int num, int *len, uae_u8 *dstptr);
 extern uae_u8 *restore_scsidev (uae_u8 *src);
@@ -184,7 +184,7 @@ extern uae_u8 *restore_cycles (uae_u8 *src);
 
 extern void restore_cram (int, size_t);
 extern void restore_bram (int, size_t);
-extern void restore_fram (int, size_t);
+extern void restore_fram (int, size_t, int);
 extern void restore_zram (int, size_t, int);
 extern void restore_bootrom (int, size_t);
 extern void restore_pram (int, size_t);
@@ -195,7 +195,7 @@ extern void restore_ram (size_t, uae_u8*);
 
 extern uae_u8 *save_cram (int *);
 extern uae_u8 *save_bram (int *);
-extern uae_u8 *save_fram (int *);
+extern uae_u8 *save_fram (int *, int);
 extern uae_u8 *save_zram (int *, int);
 extern uae_u8 *save_bootrom (int *);
 extern uae_u8 *save_pram (int *);
index c3f0ebddad7d86989081966ca8cb8a52f0a1bf34..1914a02713296050d2789875a1219f64c78d6c44 100644 (file)
@@ -21,6 +21,7 @@ struct scsi_data_tape
 struct scsi_data
 {
     int id;
+       void *privdata;
     int cmd_len;
     uae_u8 *data;
     int data_len;
index a1ca44a349d4f8088a8a3a1ed5afcc49bcad7290..6484e86dbcc373a732166666e74296efbc852bd2 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -305,13 +305,27 @@ void fixup_prefs (struct uae_prefs *p)
                p->chipmem_size = 0x200000;
                err = 1;
        }
+
        if ((p->fastmem_size & (p->fastmem_size - 1)) != 0
-               || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000)))
-{
+               || (p->fastmem_size != 0 && (p->fastmem_size < 0x10000 || p->fastmem_size > 0x800000)))
+       {
                error_log (_T("Unsupported fastmem size %d (0x%x)."), p->fastmem_size, p->fastmem_size);
                p->fastmem_size = 0;
                err = 1;
        }
+       if ((p->fastmem2_size & (p->fastmem2_size - 1)) != 0 || (p->fastmem_size + p->fastmem2_size) > 0x800000 + 262144
+               || (p->fastmem2_size != 0 && (p->fastmem2_size < 0x10000 || p->fastmem_size > 0x800000)))
+       {
+               error_log (_T("Unsupported fastmem2 size %d (0x%x)."), p->fastmem2_size, p->fastmem2_size);
+               p->fastmem2_size = 0;
+               err = 1;
+       }
+       if (p->fastmem2_size > p->fastmem_size) {
+               error_log (_T("fastmem2 size can't be larger than fastmem1."));
+               p->fastmem2_size = 0;
+               err = 1;
+       }
+
        if (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3) {
                error_log (_T("Graphics card memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), p->rtgmem_size, p->rtgmem_size, max_z3fastmem, max_z3fastmem);
                p->rtgmem_size = max_z3fastmem;
@@ -359,9 +373,9 @@ void fixup_prefs (struct uae_prefs *p)
                p->z3chipmem_size = max_z3fastmem;
                err = 1;
        }
-       if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 || (p->z3chipmem_size != 0 && p->z3chipmem_size < 0x100000))
+       if (((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 &&  p->z3chipmem_size != 0x18000000 && p->z3chipmem_size != 0x30000000) || (p->z3chipmem_size != 0 && p->z3chipmem_size < 0x100000))
        {
-               error_log (_T("Unsupported Zorro III fake chipmem size %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size);
+               error_log (_T("Unsupported 32-bit chipmem size %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size);
                p->z3chipmem_size = 0;
                err = 1;
        }
@@ -381,7 +395,7 @@ void fixup_prefs (struct uae_prefs *p)
                p->bogomem_size = 0x180000;
                error_log (_T("Possible Gayle bogomem conflict fixed."));
        }
-       if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) {
+       if (p->chipmem_size > 0x200000 && p->fastmem_size > 262144) {
                error_log (_T("You can't use fastmem and more than 2MB chip at the same time."));
                p->fastmem_size = 0;
                err = 1;
@@ -451,6 +465,14 @@ void fixup_prefs (struct uae_prefs *p)
                p->cachesize = 0;
                err = 1;
        }
+       if (!p->jit_direct_compatible_memory && p->comptrustbyte) {
+               error_log(_T("JIT direct compatible memory option is disabled, disabling JIT direct."));
+               p->comptrustbyte = 0;
+               p->comptrustlong = 0;
+               p->comptrustlong = 0;
+               p->comptrustnaddr = 0;
+               err = 1;
+       }
        if ((p->z3fastmem_size || p->z3fastmem2_size || p->z3chipmem_size) && (p->address_space_24 || p->cpu_model < 68020)) {
                error_log (_T("Z3 fast memory can't be used with a 68000/68010 emulation. Turning off Z3 fast memory."));
                p->z3fastmem_size = 0;
@@ -520,6 +542,9 @@ void fixup_prefs (struct uae_prefs *p)
                error_log (_T("Genlock and A2024 or Graffiti can't be active simultaneously."));
                p->genlock = false;
        }
+       if (p->cs_hacks) {
+               error_log (_T("chipset_hacks is nonzero."));
+       }
 
        fixup_prefs_dimensions (p);
 
index 8f573ad6b83082283019c1b9fc85dbc15877ca5d..368fbfecb69cf7d0d11fa66a244c112994abe3d7 100644 (file)
@@ -29,6 +29,7 @@
 #include "akiko.h"
 #include "arcadia.h"
 #include "enforcer.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "gayle.h"
 #include "debug.h"
@@ -757,9 +758,9 @@ static void REGPARAM3 kickmem_lput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 kickmem_wput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 kickmem_bput (uaecptr, uae_u32) REGPARAM;
 
-MEMORY_BGET(kickmem);
-MEMORY_WGET(kickmem);
-MEMORY_LGET(kickmem);
+MEMORY_BGET(kickmem, 0);
+MEMORY_WGET(kickmem, 0);
+MEMORY_LGET(kickmem, 0);
 MEMORY_CHECK(kickmem);
 MEMORY_XLATE(kickmem);
 
@@ -879,9 +880,9 @@ static void REGPARAM3 extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
 
-MEMORY_BGET(extendedkickmem);
-MEMORY_WGET(extendedkickmem);
-MEMORY_LGET(extendedkickmem);
+MEMORY_BGET(extendedkickmem, 0);
+MEMORY_WGET(extendedkickmem, 0);
+MEMORY_LGET(extendedkickmem, 0);
 MEMORY_CHECK(extendedkickmem);
 MEMORY_XLATE(extendedkickmem);
 
@@ -915,9 +916,9 @@ static void REGPARAM3 extendedkickmem2_lput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 extendedkickmem2_wput (uaecptr, uae_u32) REGPARAM;
 static void REGPARAM3 extendedkickmem2_bput (uaecptr, uae_u32) REGPARAM;
 
-MEMORY_BGET(extendedkickmem2);
-MEMORY_WGET(extendedkickmem2);
-MEMORY_LGET(extendedkickmem2);
+MEMORY_BGET(extendedkickmem2, 0);
+MEMORY_WGET(extendedkickmem2, 0);
+MEMORY_LGET(extendedkickmem2, 0);
 MEMORY_CHECK(extendedkickmem2);
 MEMORY_XLATE(extendedkickmem2);
 
@@ -1646,9 +1647,10 @@ uae_u8 *mapped_malloc (size_t s, const TCHAR *file)
        int id;
        void *answer;
        shmpiece *x;
+       bool rtgmem = !_tcsicmp(file, _T("z3_gfx")) || !_tcsicmp(file, _T("z2_gfx"));
        static int recurse;
 
-       if (!needmman ()) {
+       if (!needmman () && (!rtgmem || currprefs.cpu_model < 68020)) {
                nocanbang ();
                return xcalloc (uae_u8, s + 4);
        }
@@ -1745,8 +1747,12 @@ static void allocate_memory (void)
                int memsize;
                mapped_free (chipmem_bank.baseaddr);
                chipmem_bank.baseaddr = 0;
-               if (currprefs.chipmem_size > 2 * 1024 * 1024)
-                       free_fastmemory ();
+               if (currprefs.chipmem_size > 2 * 1024 * 1024) {
+                       if (currprefs.fastmem_size >= 524288)
+                               free_fastmemory (0);
+                       if (currprefs.fastmem2_size >= 524288)
+                               free_fastmemory (1);
+               }
 
                memsize = chipmem_bank.allocated = chipmem_full_size = currprefs.chipmem_size;
                chipmem_full_mask = chipmem_bank.mask = chipmem_bank.allocated - 1;
index 3f817d39efe9e70eff570d23eded36abf7a0ff5d..99cfa900aec7639553823822ab37b3b6f711ba6f 100644 (file)
@@ -53,6 +53,8 @@ void moduleripper (void)
        p += currprefs.chipmem_size;
        mc (p, fastmem_bank.start, currprefs.fastmem_size);
        p += currprefs.fastmem_size;
+       mc (p, fastmem2_bank.start, currprefs.fastmem2_size);
+       p += currprefs.fastmem2_size;
        mc (p, bogomem_bank.start, currprefs.bogomem_size);
        p += currprefs.bogomem_size;
        mc (p, a3000lmem_bank.start, currprefs.mbresmem_low_size);
index 7ffd84e5a681bbb91a6e1a360702d0ccd8879dc6..d4be23cc2bf6ae24ff3ad5fe0928c981eb718673 100644 (file)
 
 #define A4091_DIP_OFFSET 0x008c0003
 
-static uae_u8 *rom;
-static int board_mask;
-static int configured;
-static uae_u8 acmemory[128];
+struct ncr_state
+{
+       TCHAR *name;
+       DeviceState devobject;
+       SCSIDevice *scsid[8];
+       SCSIBus scsibus;
+       uae_u32 board_mask;
+       uae_u8 *rom;
+       uae_u8 acmemory[128];
+       uae_u32 expamem_hi;
+       uae_u32 expamem_lo;
+       int configured;
+       bool enabled;
+};
+
+static struct ncr_state ncr_a4091;
+static struct ncr_state ncr_a4091_2;
+static struct ncr_state ncr_a4000t;
 
-static DeviceState devobject;
-static SCSIDevice *scsid[8];
-static SCSIBus scsibus;
+static struct ncr_state *ncra4091[] =
+{
+       &ncr_a4091,
+       &ncr_a4091_2
+};
 
 void pci_set_irq(PCIDevice *pci_dev, int level)
 {
@@ -74,11 +90,12 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *bu
 {
        SCSIRequest *req = xcalloc(SCSIRequest, 1);
        struct scsi_data *sd = (struct scsi_data*)d->handle;
+       struct ncr_state *ncr = (struct ncr_state*)sd->privdata;
 
        req->dev = d;
        req->hba_private = hba_private;
-       req->bus = &scsibus;
-       req->bus->qbus.parent = &devobject;
+       req->bus = &ncr->scsibus;
+       req->bus->qbus.parent = &ncr->devobject;
        
        memcpy (sd->cmd, buf, len);
        sd->cmd_len = len;
@@ -111,18 +128,19 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
 }
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun)
 {
+       struct ncr_state *ncr = (struct ncr_state*)bus->privdata;
        if (lun != 0 || target < 0 || target >= 8)
                return NULL;
-       return scsid[target];
+       return ncr->scsid[target];
 }
 void scsi_req_cancel(SCSIRequest *req)
 {
        write_log (_T("scsi_req_cancel\n"));
 }
 
-static uae_u8 read_rombyte (uaecptr addr)
+static uae_u8 read_rombyte (struct ncr_state *ncr, uaecptr addr)
 {
-       uae_u8 v = rom[addr];
+       uae_u8 v = ncr->rom[addr];
        //write_log (_T("%08X = %02X PC=%08X\n"), addr, v, M68K_GETPC);
        return v;
 }
@@ -149,133 +167,116 @@ static uaecptr beswap (uaecptr addr)
        return (addr & ~3) | (3 - (addr & 3));
 }
 
-void ncr_io_bput (uaecptr addr, uae_u32 val)
+void ncr_io_bput (struct ncr_state *ncr, uaecptr addr, uae_u32 val)
 {
        addr &= A4091_IO_MASK;
-       lsi_mmio_write (devobject.lsistate, beswap (addr), val, 1);
+       lsi_mmio_write (ncr->devobject.lsistate, beswap (addr), val, 1);
 }
 
-static void ncr_bput2 (uaecptr addr, uae_u32 val)
+static void ncr_bput2 (struct ncr_state *ncr, uaecptr addr, uae_u32 val)
 {
        uae_u32 v = val;
-       addr &= board_mask;
+       addr &= ncr->board_mask;
        if (addr < A4091_IO_OFFSET || addr >= A4091_IO_END)
                return;
-       ncr_io_bput (addr, val);
+       ncr_io_bput (ncr, addr, val);
 }
 
-uae_u32 ncr_io_bget (uaecptr addr)
+uae_u32 ncr_io_bget (struct ncr_state *ncr, uaecptr addr)
 {
        addr &= A4091_IO_MASK;
-       return lsi_mmio_read (devobject.lsistate, beswap (addr), 1);
+       return lsi_mmio_read (ncr->devobject.lsistate, beswap (addr), 1);
 }
 
-static uae_u32 ncr_bget2 (uaecptr addr)
+static uae_u32 ncr_bget2 (struct ncr_state *ncr, uaecptr addr)
 {
        uae_u32 v = 0;
 
-       addr &= board_mask;
-       if (rom && addr >= ROM_VECTOR && addr < A4091_IO_OFFSET)
-               return read_rombyte (addr);
+       addr &= ncr->board_mask;
+       if (ncr->rom && addr >= ROM_VECTOR && addr < A4091_IO_OFFSET)
+               return read_rombyte (ncr, addr);
        if (addr == A4091_DIP_OFFSET)
                return 0xff;
        if (addr < A4091_IO_OFFSET || addr >= A4091_IO_END)
                return v;
        addr &= A4091_IO_MASK;
-       return ncr_io_bget (addr);
+       return ncr_io_bget (ncr, addr);
 }
 
-extern addrbank ncr_bank;
-
-static uae_u32 REGPARAM2 ncr_lget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_lget (struct ncr_state *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       addr &= board_mask;
+       addr &= ncr->board_mask;
        if (addr >= A4091_IO_ALT) {
-               v = (ncr_bget2 (addr + 3) << 0) | (ncr_bget2 (addr + 2) << 8) |
-                       (ncr_bget2 (addr + 1) << 16) | (ncr_bget2 (addr + 0) << 24);
+               v = (ncr_bget2 (ncr, addr + 3) << 0) | (ncr_bget2 (ncr, addr + 2) << 8) |
+                       (ncr_bget2 (ncr, addr + 1) << 16) | (ncr_bget2 (ncr, addr + 0) << 24);
        } else {
-               v = (ncr_bget2 (addr + 3) << 0) | (ncr_bget2 (addr + 2) << 8) |
-                       (ncr_bget2 (addr + 1) << 16) | (ncr_bget2 (addr + 0) << 24);
+               v = (ncr_bget2 (ncr, addr + 3) << 0) | (ncr_bget2 (ncr, addr + 2) << 8) |
+                       (ncr_bget2 (ncr, addr + 1) << 16) | (ncr_bget2 (ncr, addr + 0) << 24);
        }
-#if NCR_DEBUG > 0
-       if (addr < ROM_VECTOR)
-               write_log (_T("ncr_lget %08X=%08X PC=%08X\n"), addr, v, M68K_GETPC);
-#endif
        return v;
 }
 
-static uae_u32 REGPARAM2 ncr_wget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_wget (struct ncr_state *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       addr &= board_mask;
-       v = (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1);
-#if NCR_DEBUG > 0
-       if (addr < ROM_VECTOR)
-               write_log (_T("ncr_wget %08X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
-#endif
+       addr &= ncr->board_mask;
+       v = (ncr_bget2 (ncr, addr) << 8) | ncr_bget2 (ncr, addr + 1);
        return v;
 }
 
-static uae_u32 REGPARAM2 ncr_bget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_bget (struct ncr_state *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       addr &= board_mask;
-       if (!configured) {
-               if (addr >= sizeof acmemory)
+       addr &= ncr->board_mask;
+       if (!ncr->configured) {
+               if (addr >= sizeof ncr->acmemory)
                        return 0;
-               return acmemory[addr];
+               return ncr->acmemory[addr];
        }
-       v = ncr_bget2 (addr);
+       v = ncr_bget2 (ncr, addr);
        return v;
 }
 
-static void REGPARAM2 ncr_lput (uaecptr addr, uae_u32 l)
+static void REGPARAM2 ncr_lput (struct ncr_state *ncr, uaecptr addr, uae_u32 l)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       addr &= board_mask;
-#if NCR_DEBUG > 0
-       if (addr < ROM_VECTOR)
-               write_log (_T("ncr_lput %08X=%08X PC=%08X\n"), addr, l, M68K_GETPC);
-#endif
+       addr &= ncr->board_mask;
        if (addr >= A4091_IO_ALT) {
-               ncr_bput2 (addr + 3, l >> 0);
-               ncr_bput2 (addr + 2, l >> 8);
-               ncr_bput2 (addr + 1, l >> 16);
-               ncr_bput2 (addr + 0, l >> 24);
+               ncr_bput2 (ncr, addr + 3, l >> 0);
+               ncr_bput2 (ncr, addr + 2, l >> 8);
+               ncr_bput2 (ncr, addr + 1, l >> 16);
+               ncr_bput2 (ncr, addr + 0, l >> 24);
        } else {
-               ncr_bput2 (addr + 3, l >> 0);
-               ncr_bput2 (addr + 2, l >> 8);
-               ncr_bput2 (addr + 1, l >> 16);
-               ncr_bput2 (addr + 0, l >> 24);
+               ncr_bput2 (ncr, addr + 3, l >> 0);
+               ncr_bput2 (ncr, addr + 2, l >> 8);
+               ncr_bput2 (ncr, addr + 1, l >> 16);
+               ncr_bput2 (ncr, addr + 0, l >> 24);
        }
 }
 
-static uae_u32 expamem_hi, expamem_lo;
+extern addrbank ncr_bank_a4091;
+extern addrbank ncr_bank_a4091_2;
 
-static void REGPARAM2 ncr_wput (uaecptr addr, uae_u32 w)
+static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        w &= 0xffff;
-       addr &= board_mask;
-#if NCR_DEBUG > 0
-       if (addr < ROM_VECTOR)
-               write_log (_T("ncr_wput %04X=%04X PC=%08X\n"), addr, w & 65535, M68K_GETPC);
-#endif
-       if (!configured) {
+       addr &= ncr->board_mask;
+       if (!ncr->configured) {
                uae_u32 value;
                switch (addr)
                {
@@ -292,87 +293,179 @@ static void REGPARAM2 ncr_wput (uaecptr addr, uae_u32 w)
                                }
                                if (value < 0x40000000 && max_z3fastmem >= 0x41000000)
                                        value = 0x40000000;
+                               if (ncr == &ncr_a4091_2)
+                                       value += 16 * 1024 * 1024;
                                value >>= 16;
                                chipmem_wput (regs.regs[11] + 0x20, value);
                                chipmem_wput (regs.regs[11] + 0x28, value);
                        } else {
-                               expamem_hi = w & 0xff00;
-                               value = expamem_hi | (expamem_lo >> 4);
+                               ncr->expamem_hi = w & 0xff00;
+                               value = ncr->expamem_hi | (ncr->expamem_lo >> 4);
                        }
-                       map_banks (&ncr_bank, value, BOARD_SIZE >> 16, 0);
-                       board_mask = 0x00ffffff;
-                       write_log (_T("A4091 Z3 autoconfigured at %04X0000\n"), value);
-                       configured = 1;
+                       map_banks (ncr == &ncr_a4091 ? &ncr_bank_a4091 : &ncr_bank_a4091_2, value, BOARD_SIZE >> 16, 0);
+                       ncr->board_mask = 0x00ffffff;
+                       write_log (_T("%s Z3 autoconfigured at %04X0000\n"), ncr->name, value);
+                       ncr->configured = 1;
                        expamem_next();
                        break;
                }
                return;
        }
-       ncr_bput2 (addr, w >> 8);
-       ncr_bput2 (addr + 1, w);
+       ncr_bput2 (ncr, addr, w >> 8);
+       ncr_bput2 (ncr, addr + 1, w);
 }
 
-static void REGPARAM2 ncr_bput (uaecptr addr, uae_u32 b)
+static void REGPARAM2 ncr_bput (struct ncr_state *ncr, uaecptr addr, uae_u32 b)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        b &= 0xff;
-       addr &= board_mask;
-       if (!configured) {
+       addr &= ncr->board_mask;
+       if (!ncr->configured) {
                switch (addr)
                {
                        case 0x4c:
                        write_log (_T("A4091 AUTOCONFIG SHUT-UP!\n"));
-                       configured = 1;
+                       ncr->configured = 1;
                        expamem_next ();
                        break;
                        case 0x48:
-                       expamem_lo = b & 0xff;
+                       ncr->expamem_lo = b & 0xff;
                        break;
                }
                return;
        }
-       ncr_bput2 (addr, b);
+       ncr_bput2 (ncr, addr, b);
+}
+
+void ncr_io_bput_a4000t(uaecptr addr, uae_u32 v)
+{
+       ncr_io_bput(&ncr_a4000t, addr, v);
+}
+uae_u32 ncr_io_bget_a4000t(uaecptr addr)
+{
+       return ncr_io_bget(&ncr_a4000t, addr);
+}
+
+static void REGPARAM2 ncr4_bput (uaecptr addr, uae_u32 b)
+{
+       ncr_bput(&ncr_a4091, addr, b);
+}
+static void REGPARAM2 ncr4_wput (uaecptr addr, uae_u32 b)
+{
+       ncr_wput(&ncr_a4091, addr, b);
+}
+static void REGPARAM2 ncr4_lput (uaecptr addr, uae_u32 b)
+{
+       ncr_lput(&ncr_a4091, addr, b);
+}
+static uae_u32 REGPARAM2 ncr4_bget (uaecptr addr)
+{
+       return ncr_bget(&ncr_a4091, addr);
+}
+static uae_u32 REGPARAM2 ncr4_wget (uaecptr addr)
+{
+       return ncr_wget(&ncr_a4091, addr);
+}
+static uae_u32 REGPARAM2 ncr4_lget (uaecptr addr)
+{
+       return ncr_lget(&ncr_a4091, addr);
 }
 
-static addrbank ncr_bank = {
-       ncr_lget, ncr_wget, ncr_bget,
-       ncr_lput, ncr_wput, ncr_bput,
+static void REGPARAM2 ncr42_bput (uaecptr addr, uae_u32 b)
+{
+       ncr_bput(&ncr_a4091_2, addr, b);
+}
+static void REGPARAM2 ncr42_wput (uaecptr addr, uae_u32 b)
+{
+       ncr_wput(&ncr_a4091_2, addr, b);
+}
+static void REGPARAM2 ncr42_lput (uaecptr addr, uae_u32 b)
+{
+       ncr_lput(&ncr_a4091_2, addr, b);
+}
+static uae_u32 REGPARAM2 ncr42_bget (uaecptr addr)
+{
+       return ncr_bget(&ncr_a4091_2, addr);
+}
+static uae_u32 REGPARAM2 ncr42_wget (uaecptr addr)
+{
+       return ncr_wget(&ncr_a4091_2, addr);
+}
+static uae_u32 REGPARAM2 ncr42_lget (uaecptr addr)
+{
+       return ncr_lget(&ncr_a4091_2, addr);
+}
+
+static addrbank ncr_bank_a4091 = {
+       ncr4_lget, ncr4_wget, ncr4_bget,
+       ncr4_lput, ncr4_wput, ncr4_bput,
        default_xlate, default_check, NULL, _T("A4091"),
        dummy_lgeti, dummy_wgeti, ABFLAG_IO
 };
 
-static void ew (int addr, uae_u32 value)
+static addrbank ncr_bank_a4091_2 = {
+       ncr42_lget, ncr42_wget, ncr42_bget,
+       ncr42_lput, ncr42_wput, ncr42_bput,
+       default_xlate, default_check, NULL, _T("A4091 #2"),
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO
+};
+
+
+static void ew (struct ncr_state *ncr, int addr, uae_u32 value)
 {
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
-               acmemory[addr] = (value & 0xf0);
-               acmemory[addr + 2] = (value & 0x0f) << 4;
+               ncr->acmemory[addr] = (value & 0xf0);
+               ncr->acmemory[addr + 2] = (value & 0x0f) << 4;
        } else {
-               acmemory[addr] = ~(value & 0xf0);
-               acmemory[addr + 2] = ~((value & 0x0f) << 4);
+               ncr->acmemory[addr] = ~(value & 0xf0);
+               ncr->acmemory[addr + 2] = ~((value & 0x0f) << 4);
        }
 }
 
 void ncr_init (void)
 {
-       lsi_scsi_init (&devobject);
+       if (!ncr_a4091.devobject.lsistate)
+               lsi_scsi_init (&ncr_a4091.devobject);
+       if (!ncr_a4091_2.devobject.lsistate)
+               lsi_scsi_init (&ncr_a4091_2.devobject);
+       if (!ncr_a4000t.devobject.lsistate)
+               lsi_scsi_init (&ncr_a4000t.devobject);
 }
 
-void ncr_autoconfig_init (void)
+static void ncr_reset_board (struct ncr_state *ncr)
 {
+       ncr->configured = 0;
+       ncr->board_mask = 0xffff;
+       if (ncr->devobject.lsistate)
+               lsi_scsi_reset (&ncr->devobject, ncr);
+       if (ncr == &ncr_a4000t)
+               ncr->name = _T("A4000T NCR SCSI");
+       if (ncr == &ncr_a4091)
+               ncr->name = _T("A4091 SCSI");
+       if (ncr == &ncr_a4091_2)
+               ncr->name = _T("A4091 SCSI #2");
+}
+
+void ncr_autoconfig_init (int devnum)
+{
+       struct ncr_state *ncr = ncra4091[devnum];
        int roms[3];
        int i;
 
-       configured = 0;
+       if (!ncr->enabled) {
+               expamem_next();
+               return;
+       }
 
        roms[0] = 58;
        roms[1] = 57;
        roms[2] = -1;
 
-       memset (acmemory, 0xff, sizeof acmemory);
+       memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
 
-       struct zfile *z = read_rom_name (currprefs.a4091romfile);
+       struct zfile *z = read_rom_name (devnum && currprefs.a4091romfile2[0] ? currprefs.a4091romfile2 : currprefs.a4091romfile);
        if (!z) {
                struct romlist *rl = getromlistbyids(roms);
                if (rl) {
@@ -381,17 +474,17 @@ void ncr_autoconfig_init (void)
                }
        }
        if (z) {
-               write_log (_T("A4091 BOOT ROM '%s'\n"), zfile_getname (z));
-               rom = xmalloc (uae_u8, ROM_SIZE * 4);
+               write_log (_T("%s BOOT ROM '%s'\n"), ncr->name, zfile_getname (z));
+               ncr->rom = xmalloc (uae_u8, ROM_SIZE * 4);
                for (i = 0; i < ROM_SIZE; i++) {
                        uae_u8 b;
                        zfile_fread (&b, 1, 1, z);
-                       rom[i * 4 + 0] = b;
-                       rom[i * 4 + 2] = b << 4;
+                       ncr->rom[i * 4 + 0] = b;
+                       ncr->rom[i * 4 + 2] = b << 4;
                        if (i < 0x20) {
-                               acmemory[i * 4 + 0] = b;
+                               ncr->acmemory[i * 4 + 0] = b;
                        } else if (i >= 0x40 && i < 0x60) {
-                               acmemory[(i - 0x40) * 4 + 2] = b;
+                               ncr->acmemory[(i - 0x40) * 4 + 2] = b;
                        }
                }
                zfile_fclose(z);
@@ -400,10 +493,11 @@ void ncr_autoconfig_init (void)
        }
 
        ncr_init ();
-       map_banks (&ncr_bank, 0xe80000 >> 16, 65536 >> 16, 0);
+       ncr_reset_board(ncr);
+       map_banks (ncr == &ncr_a4091 ? &ncr_bank_a4091 : &ncr_bank_a4091_2, 0xe80000 >> 16, 65536 >> 16, 0);
 }
 
-static void freescsi (struct scsi_data *sd)
+static void freescsi_hdf (struct scsi_data *sd)
 {
        if (!sd)
                return;
@@ -414,36 +508,40 @@ static void freescsi (struct scsi_data *sd)
 static void freescsi (SCSIDevice *scsi)
 {
        if (scsi) {
-               freescsi ((struct scsi_data*)scsi->handle);
+               freescsi_hdf ((struct scsi_data*)scsi->handle);
                xfree (scsi);
        }
 }
 
-void ncr_free (void)
+void ncr_free2(struct ncr_state *ncr)
 {
        for (int ch = 0; ch < 8; ch++) {
-               freescsi (scsid[ch]);
-               scsid[ch] = NULL;
+               freescsi (ncr->scsid[ch]);
+               ncr->scsid[ch] = NULL;
        }
 }
 
+void ncr_free(void)
+{
+       ncr_free2(&ncr_a4000t);
+       ncr_free2(&ncr_a4091);
+       ncr_free2(&ncr_a4091_2);
+}
+
 void ncr_reset (void)
 {
-       configured = 0;
-       board_mask = 0xffff;
-       if (currprefs.cs_mbdmac == 2) {
-               configured = -1;
-       }
-       if (devobject.lsistate)
-               lsi_scsi_reset (&devobject);
+       ncr_reset_board(&ncr_a4091);
+       ncr_reset_board(&ncr_a4091_2);
+       ncr_reset_board(&ncr_a4000t);
+       if (currprefs.cs_mbdmac & 2)
+               ncr_a4000t.configured = -1;
 }
 
-static int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
+static int add_ncr_scsi_hd (struct ncr_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
 {
-       void *handle;
-       
-       freescsi (scsid[ch]);
-       scsid[ch] = NULL;
+       struct scsi_data *handle;
+       freescsi (ncr->scsid[ch]);
+       ncr->scsid[ch] = NULL;
        if (!hfd) {
                hfd = xcalloc (struct hd_hardfiledata, 1);
                memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
@@ -454,57 +552,64 @@ static int add_scsi_hd (int ch, struct hd_hardfiledata *hfd, struct uaedev_confi
        handle = scsi_alloc_hd (ch, hfd);
        if (!handle)
                return 0;
-       scsid[ch] = xcalloc (SCSIDevice, 1);
-       scsid[ch]->handle = handle;
-       return scsid[ch] ? 1 : 0;
+       handle->privdata = ncr;
+       ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
+       ncr->scsid[ch]->handle = handle;
+       ncr->enabled = true;
+       return ncr->scsid[ch] ? 1 : 0;
 }
 
 
-static int add_scsi_cd (int ch, int unitnum)
+static int add_ncr_scsi_cd (struct ncr_state *ncr, int ch, int unitnum)
 {
-       void *handle;
+       struct scsi_data *handle;
        device_func_init (0);
-       freescsi (scsid[ch]);
-       scsid[ch] = NULL;
+       freescsi (ncr->scsid[ch]);
+       ncr->scsid[ch] = NULL;
        handle = scsi_alloc_cd (ch, unitnum, false);
        if (!handle)
                return 0;
-       scsid[ch] = xcalloc (SCSIDevice, 1);
-       scsid[ch]->handle = handle;
-       return scsid[ch] ? 1 : 0;
+       handle->privdata = ncr;
+       ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
+       ncr->scsid[ch]->handle = handle;
+       ncr->enabled = true;
+       return ncr->scsid[ch] ? 1 : 0;
 }
 
-static int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly)
+static int add_ncr_scsi_tape (struct ncr_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
 {
-       void *handle;
-       freescsi (scsid[ch]);
-       scsid[ch] = NULL;
+       struct scsi_data *handle;
+       freescsi (ncr->scsid[ch]);
+       ncr->scsid[ch] = NULL;
        handle = scsi_alloc_tape (ch, tape_directory, readonly);
        if (!handle)
                return 0;
-       scsid[ch] = xcalloc (SCSIDevice, 1);
-       scsid[ch]->handle = handle;
-       return scsid[ch] ? 1 : 0;
+       handle->privdata = ncr;
+       ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
+       ncr->scsid[ch]->handle = handle;
+       ncr->enabled = true;
+       return ncr->scsid[ch] ? 1 : 0;
 }
 
 int a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci)
 {
        if (ci->type == UAEDEV_CD)
-               return add_scsi_cd (ch, ci->device_emu_unit);
+               return add_ncr_scsi_cd (&ncr_a4000t, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+               return add_ncr_scsi_tape (&ncr_a4000t, ch, ci->rootdir, ci->readonly);
        else
-               return add_scsi_hd (ch, NULL, ci, 1);
+               return add_ncr_scsi_hd (&ncr_a4000t, ch, NULL, ci, 1);
 }
 
-int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum)
 {
+       struct ncr_state *ncr = ncra4091[devnum];
        if (ci->type == UAEDEV_CD)
-               return add_scsi_cd (ch, ci->device_emu_unit);
+               return add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape (ch, ci->rootdir, ci->readonly);
+               return add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
        else
-               return add_scsi_hd (ch, NULL, ci, 1);
+               return add_ncr_scsi_hd (ncr, ch, NULL, ci, 1);
 }
 
 
index 3d88104b214cda9ebea43c0461a03b68394ff5e1..1c573b3cfce3e19363131e542948687e34f27a3b 100644 (file)
@@ -195,6 +195,31 @@ void (*x_do_cycles)(unsigned long);
 void (*x_do_cycles_pre)(unsigned long);
 void (*x_do_cycles_post)(unsigned long, uae_u32);
 
+static void set_x_cp_funcs(void)
+{
+       x_cp_put_long = x_put_long;
+       x_cp_put_word = x_put_word;
+       x_cp_put_byte = x_put_byte;
+       x_cp_get_long = x_get_long;
+       x_cp_get_word = x_get_word;
+       x_cp_get_byte = x_get_byte;
+       x_cp_next_iword = x_next_iword;
+       x_cp_next_ilong = x_next_ilong;
+       x_cp_get_disp_ea_020 = x_get_disp_ea_020;
+
+       if (currprefs.mmu_model == 68030) {
+               x_cp_put_long = put_long_mmu030_state;
+               x_cp_put_word = put_word_mmu030_state;
+               x_cp_put_byte = put_byte_mmu030_state;
+               x_cp_get_long = get_long_mmu030_state;
+               x_cp_get_word = get_word_mmu030_state;
+               x_cp_get_byte = get_byte_mmu030_state;
+               x_cp_next_iword = next_iword_mmu030_state;
+               x_cp_next_ilong = next_ilong_mmu030_state;
+               x_cp_get_disp_ea_020 = get_disp_ea_020_mmu030;
+       }
+}
+
 static struct cputracestruct cputrace;
 
 #if CPUTRACE_DEBUG
@@ -301,6 +326,7 @@ static bool check_trace (void)
        x_do_cycles = x2_do_cycles;
        x_do_cycles_pre = x2_do_cycles_pre;
        x_do_cycles_post = x2_do_cycles_post;
+       set_x_cp_funcs();
        write_log (_T("CPU tracer playback complete. STARTCYCLES=%08x NOWCYCLES=%08x\n"), cputrace.startcycles, get_cycles ());
        cputrace.needendcycles = 1;
        cpu_tracer = 0;
@@ -908,27 +934,7 @@ static void set_x_funcs (void)
                }
        }
 
-       x_cp_put_long = x_put_long;
-       x_cp_put_word = x_put_word;
-       x_cp_put_byte = x_put_byte;
-       x_cp_get_long = x_get_long;
-       x_cp_get_word = x_get_word;
-       x_cp_get_byte = x_get_byte;
-       x_cp_next_iword = x_next_iword;
-       x_cp_next_ilong = x_next_ilong;
-       x_cp_get_disp_ea_020 = x_get_disp_ea_020;
-
-       if (currprefs.mmu_model == 68030) {
-               x_cp_put_long = put_long_mmu030_state;
-               x_cp_put_word = put_word_mmu030_state;
-               x_cp_put_byte = put_byte_mmu030_state;
-               x_cp_get_long = get_long_mmu030_state;
-               x_cp_get_word = get_word_mmu030_state;
-               x_cp_get_byte = get_byte_mmu030_state;
-               x_cp_next_iword = next_iword_mmu030_state;
-               x_cp_next_ilong = next_ilong_mmu030_state;
-               x_cp_get_disp_ea_020 = get_disp_ea_020_mmu030;
-       }
+       set_x_cp_funcs();
 
 }
 
@@ -2899,7 +2905,7 @@ static void mmu_op30fake_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecpt
                write_log (_T(" PC=%08X\n"), pc);
        }
 #endif
-       if (currprefs.cs_mbdmac == 1 && currprefs.mbresmem_low_size > 0) {
+       if ((currprefs.cs_mbdmac & 1) && currprefs.mbresmem_low_size > 0) {
                if (otc != fake_tc_030) {
                        a3000_fakekick (fake_tc_030 & 0x80000000);
                }
index 29fb3f9f4796cffe75c6b33720ff49503988ac14..b5328708a0dc757bd5c305ff751bb07fd322d5b3 100644 (file)
@@ -763,6 +763,16 @@ bool my_createsoftlink(const TCHAR *path, const TCHAR *target)
        return CreateSymbolicLink(path, target, my_existsdir (target) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != 0;
 }
 
+bool my_issamepath(const TCHAR *path1, const TCHAR *path2)
+{
+       TCHAR path1o[MAX_DPATH], path2o[MAX_DPATH];
+       my_canonicalize_path(path1, path1o, sizeof path1o / sizeof(TCHAR));
+       my_canonicalize_path(path2, path2o, sizeof path2o / sizeof(TCHAR));
+       if (!_tcsicmp(path1o, path2o))
+               return true;
+       return false;
+}
+
 void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size)
 {
        TCHAR tmp[MAX_DPATH];
index 07e4b4e9a0d6df7a1be4daa0563e24c64aa53de5..25bc03cf2bc1d1873c78a4b4f32dbf609c78c12a 100644 (file)
@@ -1942,7 +1942,7 @@ int win32_hardfile_media_change (const TCHAR *drvname, int inserted)
                extern struct hd_hardfiledata *pcmcia_sram;
                int reopen = 0;
                struct uaedev_config_data *uci = &currprefs.mountconfig[i];
-               if (uci->ci.controller == HD_CONTROLLER_PCMCIA_SRAM) {
+               if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
                        hmc_check (&pcmcia_sram->hfd, uci, &rescanned, &reopen, &gotinsert, drvname, inserted);
                }
        }
index fc61a6cb1fa4a1dce2ba1273e8d98a70152826ad..4fd0daa6818ff28e96de11bd257fe7f0c17112b3 100644 (file)
@@ -15,8 +15,6 @@
 
 #if defined(NATMEM_OFFSET)
 
-#define VAMODE 1
-
 uae_u32 max_z3fastmem;
 
 /* JIT can access few bytes outside of memory block if it executes code at the very end of memory block */
@@ -26,9 +24,11 @@ uae_u32 max_z3fastmem;
 #define MAXZ3MEM64 0xF0000000
 
 static struct shmid_ds shmids[MAX_SHMID];
-uae_u8 *natmem_offset, *natmem_offset_end;
+uae_u8 *natmem_offset_allocated, *natmem_offset, *natmem_offset_end;
 static uae_u8 *p96mem_offset;
 static int p96mem_size;
+static uae_u32 p96base_offset;
+static void *rtgmem_mapped_memory;
 static SYSTEM_INFO si;
 int maxmem;
 uae_u32 natmem_size;
@@ -53,19 +53,6 @@ uae_u8 *cache_alloc (int size)
        return virtualallocwithlock (NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 }
 
-#if 0
-static void setworkingset(void)
-{
-       typedef BOOL (CALLBACK* SETPROCESSWORKINGSETSIZE)(HANDLE,SIZE_T,SIZE_T);
-       SETPROCESSWORKINGSETSIZE pSetProcessWorkingSetSize;
-       pSetProcessWorkingSetSize = (SETPROCESSWORKINGSETSIZE)GetProcAddress(GetModuleHandle("kernal32.dll", "GetProcessWorkingSetSize");
-       if (!pSetProcessWorkingSetSize)
-               return;
-       pSetProcessWorkingSetSize(GetCurrentProcess (),
-               );
-}
-#endif
-
 static uae_u32 lowmem (void)
 {
        uae_u32 change = 0;
@@ -128,8 +115,9 @@ bool preinit_shm (void)
        MEMORYSTATUSEX memstatsex;
        uae_u32 max_allowed_mman;
 
-       if (natmem_offset)
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
+       if (natmem_offset_allocated)
+               VirtualFree (natmem_offset_allocated, 0, MEM_RELEASE);
+       natmem_offset_allocated = NULL;
        natmem_offset = NULL;
        if (p96mem_offset)
                VirtualFree (p96mem_offset, 0, MEM_RELEASE);
@@ -190,28 +178,28 @@ bool preinit_shm (void)
                natmem_size = 17 * 1024 * 1024;
 
        write_log (_T("Total physical RAM %lluM, all RAM %lluM. Attempting to reserve: %uM.\n"), totalphys64 >> 20, total64 >> 20, natmem_size >> 20);
-       natmem_offset = 0;
+       natmem_offset_allocated = 0;
        if (natmem_size <= 768 * 1024 * 1024) {
                uae_u32 p = 0x78000000 - natmem_size;
                for (;;) {
-                       natmem_offset = (uae_u8*)VirtualAlloc ((void*)p, natmem_size, MEM_RESERVE | (VAMODE == 1 ? MEM_WRITE_WATCH : 0), PAGE_READWRITE);
-                       if (natmem_offset)
+                       natmem_offset_allocated = (uae_u8*)VirtualAlloc ((void*)p, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
+                       if (natmem_offset_allocated)
                                break;
                        p -= 128 * 1024 * 1024;
                        if (p <= 128 * 1024 * 1024)
                                break;
                }
        }
-       if (!natmem_offset) {
+       if (!natmem_offset_allocated) {
                for (;;) {
-                       natmem_offset = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | (VAMODE == 1 ? MEM_WRITE_WATCH : 0) | MEM_TOP_DOWN, PAGE_READWRITE);
-                       if (natmem_offset)
+                       natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH | MEM_TOP_DOWN, PAGE_READWRITE);
+                       if (natmem_offset_allocated)
                                break;
                        natmem_size -= 128 * 1024 * 1024;
                        if (!natmem_size) {
                                write_log (_T("Can't allocate 257M of virtual address space!?\n"));
                                natmem_size = 17 * 1024 * 1024;
-                               natmem_offset = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | (VAMODE == 1 ? MEM_WRITE_WATCH : 0) | MEM_TOP_DOWN, PAGE_READWRITE);
+                               natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH | MEM_TOP_DOWN, PAGE_READWRITE);
                                if (!natmem_size) {
                                        write_log (_T("Can't allocate 17M of virtual address space!? Something is seriously wrong\n"));
                                        return false;
@@ -220,6 +208,7 @@ bool preinit_shm (void)
                        }
                }
        }
+       natmem_offset = natmem_offset_allocated;
        if (natmem_size <= 257 * 1024 * 1024)
                max_z3fastmem = 0;
        else
@@ -269,156 +258,19 @@ static void resetmem (bool decommit)
        }
 }
 
-static ULONG getz2rtgaddr (void)
+static ULONG getz2rtgaddr (int rtgsize)
 {
        ULONG start;
        start = changed_prefs.fastmem_size;
+       if (changed_prefs.fastmem2_size >= 524288)
+               start += changed_prefs.fastmem2_size;
+       start += rtgsize - 1;
+       start &= ~(rtgsize - 1);
        while (start & (changed_prefs.rtgmem_size - 1) && start < 4 * 1024 * 1024)
                start += 1024 * 1024;
        return start + 2 * 1024 * 1024;
 }
 
-#if 0
-int init_shm (void)
-{
-       uae_u32 size, totalsize, z3size, natmemsize;
-       uae_u32 rtgbarrier, z3chipbarrier, rtgextra;
-       int rounds = 0;
-       ULONG z3rtgmem_size = currprefs.rtgmem_type ? currprefs.rtgmem_size : 0;
-
-restart:
-       for (;;) {
-               int lowround = 0;
-               uae_u8 *blah = NULL;
-               if (rounds > 0)
-                       write_log (_T("NATMEM: retrying %d..\n"), rounds);
-               rounds++;
-               if (natmem_offset)
-                       VirtualFree (natmem_offset, 0, MEM_RELEASE);
-               natmem_offset = NULL;
-               natmem_offset_end = NULL;
-               canbang = 0;
-
-               z3size = 0;
-               size = 0x1000000;
-               rtgextra = 0;
-               z3chipbarrier = 0;
-               rtgbarrier = si.dwPageSize;
-               if (currprefs.cpu_model >= 68020)
-                       size = 0x10000000;
-               if (currprefs.z3fastmem_size || currprefs.z3fastmem2_size || currprefs.z3chipmem_size) {
-                       z3size = currprefs.z3fastmem_size + currprefs.z3fastmem2_size + currprefs.z3chipmem_size + (currprefs.z3fastmem_start - 0x10000000);
-                       if (z3rtgmem_size) {
-                               rtgbarrier = 16 * 1024 * 1024 - ((currprefs.z3fastmem_size + currprefs.z3fastmem2_size) & 0x00ffffff);
-                       }
-                       if (currprefs.z3chipmem_size && (currprefs.z3fastmem_size || currprefs.z3fastmem2_size))
-                               z3chipbarrier = 16 * 1024 * 1024;
-               } else {
-                       rtgbarrier = 0;
-               }
-               totalsize = size + z3size + z3rtgmem_size;
-               while (totalsize > size64) {
-                       int change = lowmem ();
-                       if (!change)
-                               return 0;
-                       write_log (_T("NATMEM: %d, %dM > %dM = %dM\n"), ++lowround, totalsize >> 20, size64 >> 20, (totalsize - change) >> 20);
-                       totalsize -= change;
-               }
-               if ((rounds > 1 && totalsize < 0x10000000) || rounds > 20) {
-                       write_log (_T("NATMEM: No special area could be allocated (3)!\n"));
-                       return 0;
-               }
-               natmemsize = size + z3size;
-
-               if (z3rtgmem_size) {
-                       rtgextra = si.dwPageSize;
-               } else {
-                       rtgbarrier = 0;
-                       rtgextra = 0;
-               }
-               natmem_size = natmemsize + rtgbarrier + z3chipbarrier + z3rtgmem_size + rtgextra + 16 * si.dwPageSize;
-               blah = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE, PAGE_READWRITE);
-               if (blah) {
-                       natmem_offset = blah;
-                       break;
-               }
-               natmem_size = 0;
-               write_log (_T("NATMEM: %dM area failed to allocate, err=%d (Z3=%dM,RTG=%dM)\n"),
-                       natmemsize >> 20, GetLastError (), (currprefs.z3fastmem_size + currprefs.z3fastmem2_size + currprefs.z3chipmem_size) >> 20, z3rtgmem_size >> 20);
-               if (!lowmem ()) {
-                       write_log (_T("NATMEM: No special area could be allocated (2)!\n"));
-                       return 0;
-               }
-       }
-       p96mem_size = z3rtgmem_size;
-       if (currprefs.rtgmem_size && currprefs.rtgmem_type) {
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
-               if (!VirtualAlloc (natmem_offset, natmemsize + rtgbarrier + z3chipbarrier, MEM_RESERVE, PAGE_READWRITE)) {
-                       write_log (_T("VirtualAlloc() part 2 error %d. RTG disabled.\n"), GetLastError ());
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       rtgbarrier = si.dwPageSize;
-                       rtgextra = 0;
-                       goto restart;
-               }
-               p96mem_offset = (uae_u8*)VirtualAlloc (natmem_offset + natmemsize + rtgbarrier + z3chipbarrier, p96mem_size + rtgextra,
-                       MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
-               if (!p96mem_offset) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       z3rtgmem_size = 0;
-                       write_log (_T("NATMEM: failed to allocate special Picasso96 GFX RAM, err=%d\n"), GetLastError ());
-               }
-       } else if (currprefs.rtgmem_size && !currprefs.rtgmem_type) {
-               // This so annoying..
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
-               // Chip + Z2Fast
-               if (!VirtualAlloc (natmem_offset, 2 * 1024 * 1024 + currprefs.fastmem_size, MEM_RESERVE, PAGE_READWRITE)) {
-                       write_log (_T("VirtualAlloc() part 2 error %d. RTG disabled.\n"), GetLastError ());
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       rtgbarrier = si.dwPageSize;
-                       rtgextra = 0;
-                       goto restart;
-               }
-               // After RTG
-               if (!VirtualAlloc (natmem_offset + 2 * 1024 * 1024 + 8 * 1024 * 1024,
-                       natmemsize + rtgbarrier + z3chipbarrier - (2 * 1024 * 1024 + 8 * 1024 * 1024) + si.dwPageSize, MEM_RESERVE, PAGE_READWRITE)) {
-                       write_log (_T("VirtualAlloc() part 2 error %d. RTG disabled.\n"), GetLastError ());
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       rtgbarrier = si.dwPageSize;
-                       rtgextra = 0;
-                       goto restart;
-               }
-               // RTG
-               p96mem_offset = (uae_u8*)VirtualAlloc (natmem_offset + getz2rtgaddr (), 10 * 1024 * 1024 - getz2rtgaddr (),
-                       MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
-               if (!p96mem_offset) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       write_log (_T("NATMEM: failed to allocate special Picasso96 GFX RAM, err=%d\n"), GetLastError ());
-               }
-       }
-
-       if (!natmem_offset) {
-               write_log (_T("NATMEM: No special area could be allocated! (1) err=%d\n"), GetLastError ());
-       } else {
-               write_log (_T("NATMEM: Our special area: 0x%p-0x%p (%08x %dM)\n"),
-                       natmem_offset, (uae_u8*)natmem_offset + natmemsize,
-                       natmemsize, natmemsize >> 20);
-               if (currprefs.rtgmem_size)
-                       write_log (_T("NATMEM: P96 special area: 0x%p-0x%p (%08x %dM)\n"),
-                       p96mem_offset, (uae_u8*)p96mem_offset + currprefs.rtgmem_size,
-                       currprefs.rtgmem_size, currprefs.rtgmem_size >> 20);
-               canbang = 1;
-               if (p96mem_size)
-                       natmem_offset_end = p96mem_offset + p96mem_size;
-               else
-                       natmem_offset_end = natmem_offset + natmemsize;
-       }
-
-       resetmem (false);
-
-       return canbang;
-}
-#endif
-
 static uae_u8 *va (uae_u32 offset, uae_u32 len, DWORD alloc, DWORD protect)
 {
        uae_u8 *addr;
@@ -436,8 +288,8 @@ static uae_u8 *va (uae_u32 offset, uae_u32 len, DWORD alloc, DWORD protect)
 
 static int doinit_shm (void)
 {
-       uae_u32 size, totalsize, z3size, natmemsize;
-       uae_u32 startbarrier;
+       uae_u32 size, totalsize, z3size, natmemsize, othersize;
+       uae_u32 startbarrier, z3offset, align;
        int rounds = 0;
        ULONG z3rtgmem_size;
 
@@ -448,15 +300,18 @@ static int doinit_shm (void)
                        write_log (_T("NATMEM: retrying %d..\n"), rounds);
                rounds++;
 
+               align = 16 * 1024 * 1024 - 1;
                z3size = 0;
+               othersize = 0;
                size = 0x1000000;
                startbarrier = changed_prefs.mbresmem_high_size == 128 * 1024 * 1024 ? 16 * 1024 * 1024 : 0;
                z3rtgmem_size = gfxboard_is_z3 (changed_prefs.rtgmem_type) ? changed_prefs.rtgmem_size : 0;
                if (changed_prefs.cpu_model >= 68020)
                        size = 0x10000000;
-               if (changed_prefs.z3fastmem_size || changed_prefs.z3fastmem2_size || changed_prefs.z3chipmem_size)
-                       z3size = changed_prefs.z3fastmem_size + changed_prefs.z3fastmem2_size + changed_prefs.z3chipmem_size + (changed_prefs.z3fastmem_start - 0x10000000);
-               totalsize = size + z3size + z3rtgmem_size;
+               z3size = ((changed_prefs.z3fastmem_size + align) & ~align) + ((changed_prefs.z3fastmem2_size + align) & ~align) + ((changed_prefs.z3chipmem_size + align) & ~align);
+               if (currprefs.a4091)
+                       othersize += 2 * 16 * 1024 * 1024;
+               totalsize = size + z3size + z3rtgmem_size + othersize;
                while (totalsize > size64) {
                        int change = lowmem ();
                        if (!change)
@@ -480,82 +335,38 @@ static int doinit_shm (void)
                }
        }
 
-#if VAMODE == 1
+       z3offset = 0;
+       if ((changed_prefs.z3fastmem_start == 0x10000000 || changed_prefs.z3fastmem_start == 0x40000000) && !changed_prefs.force_0x10000000_z3) {
+               if (natmem_size > 0x40000000 && natmem_size - 0x40000000 >= (totalsize - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align)) && changed_prefs.z3chipmem_size <= 512 * 1024 * 1024) {
+                       changed_prefs.z3fastmem_start = currprefs.z3fastmem_start = 0x40000000;
+                       z3offset += 0x40000000 - 0x10000000 -  ((changed_prefs.z3chipmem_size + align) & ~align);
+               } else {
+                       changed_prefs.z3fastmem_start = currprefs.z3fastmem_start = 0x10000000;
+               }
+       }
 
        p96mem_offset = NULL;
        p96mem_size = z3rtgmem_size;
+       p96base_offset = 0;
        if (changed_prefs.rtgmem_size && gfxboard_is_z3 (changed_prefs.rtgmem_type)) {
-               p96mem_offset = natmem_offset + natmemsize + startbarrier;
+               p96base_offset = natmemsize + startbarrier + z3offset;
        } else if (changed_prefs.rtgmem_size && !gfxboard_is_z3 (changed_prefs.rtgmem_type)) {
-               p96mem_offset = natmem_offset + getz2rtgaddr ();
+               p96base_offset = getz2rtgaddr (changed_prefs.rtgmem_size);
        }
-
-#else
-
-       if (p96mem_offset)
-               VirtualFree (p96mem_offset, 0, MEM_RELEASE);
-       p96mem_offset = NULL;
-       p96mem_size = z3rtgmem_size;
-       if (changed_prefs.rtgmem_size && changed_prefs.rtgmem_type) {
-               uae_u32 s, l;
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
-
-               s = 0;
-               l = natmemsize + rtgbarrier + z3chipbarrier;
-               if (!va (s, l, MEM_RESERVE, PAGE_READWRITE))
-                       return 0;
-
-               s = natmemsize + rtgbarrier + z3chipbarrier;
-               l = p96mem_size + rtgextra;
-               p96mem_offset = va (s, l, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
-               if (!p96mem_offset) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-                       z3rtgmem_size = 0;
-                       write_log (_T("NATMEM: failed to allocate special Picasso96 GFX RAM, err=%d\n"), GetLastError ());
-               }
-
-#if 0
-               s = natmemsize + rtgbarrier + z3chipbarrier + p96mem_size + rtgextra + 4096;
-               l = natmem_size - s - 4096;
-               if (natmem_size > l) {
-                       if (!va (s, l,  MEM_RESERVE, PAGE_READWRITE))
-                               return 0;
-               }
-#endif
-
-       } else if (changed_prefs.rtgmem_size && !changed_prefs.rtgmem_type) {
-
-               uae_u32 s, l;
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
-               // Chip + Z2Fast
-               s = 0;
-               l = 2 * 1024 * 1024 + changed_prefs.fastmem_size;
-               if (!va (s, l, MEM_RESERVE, PAGE_READWRITE)) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-               }
-               // After RTG
-               s = 2 * 1024 * 1024 + 8 * 1024 * 1024;
-               l = natmem_size - (2 * 1024 * 1024 + 8 * 1024 * 1024) + si.dwPageSize;
-               if (!va (s, l, MEM_RESERVE, PAGE_READWRITE)) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-               }
-               // RTG
-               s = getz2rtgaddr ();
-               l = 10 * 1024 * 1024 - getz2rtgaddr ();
-               p96mem_offset = va (s, l, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE);
-               if (!p96mem_offset) {
-                       currprefs.rtgmem_size = changed_prefs.rtgmem_size = 0;
-               }
-
-       } else {
-
-               VirtualFree (natmem_offset, 0, MEM_RELEASE);
-               if (!VirtualAlloc (natmem_offset, natmem_size, MEM_RESERVE, PAGE_READWRITE)) {
-                       write_log (_T("NATMEM: No special area could be reallocated! (1) err=%d\n"), GetLastError ());
-                       return 0;
+       if (p96base_offset) {
+               if (changed_prefs.jit_direct_compatible_memory) {
+                       p96mem_offset = natmem_offset + p96base_offset;
+               } else {
+                       // adjust p96mem_offset to beginning of natmem
+                       // by subtracting start of original p96mem_offset from natmem_offset
+                       if (p96base_offset >= 0x10000000) {
+                               natmem_offset = natmem_offset_allocated - 0x40000000 - (p96base_offset - 0x10000000);
+                               p96base_offset += 0x40000000 - 0x10000000;
+                               p96mem_offset = natmem_offset + p96base_offset;
+                       }
                }
        }
-#endif
+
        if (!natmem_offset) {
                write_log (_T("NATMEM: No special area could be allocated! err=%d\n"), GetLastError ());
        } else {
@@ -566,7 +377,7 @@ static int doinit_shm (void)
                        write_log (_T("NATMEM: P96 special area: 0x%p-0x%p (%08x %dM)\n"),
                        p96mem_offset, (uae_u8*)p96mem_offset + changed_prefs.rtgmem_size,
                        changed_prefs.rtgmem_size, changed_prefs.rtgmem_size >> 20);
-               canbang = 1;
+               canbang = changed_prefs.jit_direct_compatible_memory ? 1 : 0;
                if (p96mem_size)
                        natmem_offset_end = p96mem_offset + p96mem_size;
                else
@@ -616,12 +427,17 @@ void mapped_free (uae_u8 *mem)
 {
        shmpiece *x = shm_start;
 
-       if (!currprefs.jit_direct_compatible_memory) {
-               xfree (mem);
-               return;
-       }
        if (mem == NULL)
                return;
+
+       if (!currprefs.jit_direct_compatible_memory && mem != rtgmem_mapped_memory) {
+               xfree(mem);
+               return;
+       }
+
+       if (mem == rtgmem_mapped_memory)
+               rtgmem_mapped_memory = NULL;
+
        if (mem == filesysory) {
                while(x) {
                        if (mem == x->native_address) {
@@ -728,16 +544,37 @@ void *shmat (int shmid, void *shmaddr, int shmflg)
                        readonly = TRUE;
                        readonlysize = RTAREA_TRAPS;
                } else if(!_tcscmp (shmids[shmid].name, _T("fast"))) {
+                       got = TRUE;
+                       if (size < 524288) {
+                               shmaddr=natmem_offset + 0xec0000;
+                       } else {
+                               shmaddr=natmem_offset + 0x200000;
+                               if (!(currprefs.rtgmem_size && gfxboard_is_z3 (currprefs.rtgmem_type)))
+                                       size += BARRIER;
+                       }
+               } else if(!_tcscmp (shmids[shmid].name, _T("fast2"))) {
+                       got = TRUE;
+                       if (size < 524288) {
+                               shmaddr=natmem_offset + 0xec0000;
+                       } else {
+                               shmaddr=natmem_offset + 0x200000;
+                               if (currprefs.fastmem_size >= 524288)
+                                       shmaddr=natmem_offset + 0x200000 + currprefs.fastmem_size;
+                               if (!(currprefs.rtgmem_size && gfxboard_is_z3 (currprefs.rtgmem_type)))
+                                       size += BARRIER;
+                       }
+               } else if(!_tcscmp (shmids[shmid].name, _T("fast2"))) {
                        shmaddr=natmem_offset + 0x200000;
                        got = TRUE;
                        if (!(currprefs.rtgmem_size && gfxboard_is_z3 (currprefs.rtgmem_type)))
                                size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("z2_gfx"))) {
-                       ULONG start = getz2rtgaddr ();
+                       ULONG start = getz2rtgaddr (size);
                        got = TRUE;
                        p96special = TRUE;
                        shmaddr = natmem_offset + start;
                        gfxmem_bank.start = start;
+                       rtgmem_mapped_memory = shmaddr;
                        if (start + currprefs.rtgmem_size < 10 * 1024 * 1024)
                                size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("ramsey_low"))) {
@@ -766,6 +603,7 @@ void *shmat (int shmid, void *shmaddr, int shmflg)
                        p96special = TRUE;
                        gfxmem_bank.start = p96mem_offset - natmem_offset;
                        shmaddr = natmem_offset + gfxmem_bank.start;
+                       rtgmem_mapped_memory = shmaddr;
                        size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("bogo"))) {
                        shmaddr=natmem_offset+0x00C00000;
index 9a11f7acf79d7a172074a31f8d60f92d4e480fdc..eaeb804cb4eec640e44089f9865f653c8728cd80 100644 (file)
@@ -359,7 +359,6 @@ int regexiststree (UAEREG *root, const TCHAR *name)
        }
 }
 
-
 UAEREG *regcreatetree (UAEREG *root, const TCHAR *name)
 {
        UAEREG *fkey;
@@ -407,14 +406,9 @@ void regclosetree (UAEREG *key)
        xfree (key);
 }
 
-static uae_u8 crcok[20] = { 0xaf,0xb7,0x36,0x15,0x05,0xca,0xe6,0x9d,0x23,0x17,0x4d,0x50,0x2b,0x5c,0xc3,0x64,0x38,0xb8,0x4e,0xfc };
-
 int reginitializeinit (TCHAR **pppath)
 {
        UAEREG *r = NULL;
-       TCHAR tmp1[1000];
-       uae_u8 crc[20];
-       int s, v1, v2, v3;
        TCHAR path[MAX_DPATH], fpath[MAX_PATH];
        FILE *f;
        TCHAR *ppath = *pppath;
@@ -451,29 +445,6 @@ int reginitializeinit (TCHAR **pppath)
        inipath = my_strdup (fpath);
        if (!regexists (NULL, _T("Version")))
                goto fail;
-       r = regcreatetree (NULL, _T("Warning"));
-       if (!r)
-               goto fail;
-       memset (tmp1, 0, sizeof tmp1);
-       s = 200;
-       if (!regquerystr (r, _T("info1"), tmp1, &s))
-               goto fail;
-       if (!regquerystr (r, _T("info2"), tmp1 + 200, &s))
-               goto fail;
-       get_sha1 (tmp1, sizeof tmp1, crc);
-       if (memcmp (crc, crcok, sizeof crcok))
-               goto fail;
-       v1 = v2 = -1;
-       regsetint (r, _T("check"), 1);
-       regqueryint (r, _T("check"), &v1);
-       regsetint (r, _T("check"), 3);
-       regqueryint (r, _T("check"), &v2);
-       regdelete (r, _T("check"));
-       if (regqueryint (r, _T("check"), &v3))
-               goto fail;
-       if (v1 != 1 || v2 != 3)
-               goto fail;
-       regclosetree (r);
        return 1;
 fail:
        regclosetree (r);
@@ -487,12 +458,6 @@ fail:
                fwrite (bom, sizeof (bom), 1, f);
                fclose (f);
        }
-       r = regcreatetree (NULL, _T("Warning"));
-       if (!r)
-               goto end;
-       regsetstr (r, _T("info1"), _T("This is unsupported file. Compatibility between versions is not guaranteed."));
-       regsetstr (r, _T("info2"), _T("Incompatible ini-files may be re-created from scratch!"));
-       regclosetree (r);
        if (*pppath == NULL)
                *pppath = my_strdup (path);
        return 1;
@@ -505,10 +470,12 @@ end:
 void regstatus (void)
 {
        if (inimode)
-               write_log (_T("WARNING: Unsupported '%s' enabled\n"), inipath);
+               write_log (_T("'%s' enabled\n"), inipath);
 }
 
 int getregmode (void)
 {
+       if (!inimode)
+               return 0;
        return inimode;
 }
index 58e39ebf9912db2ac364d4cb6ef79ee13bceabc8..710d7fd65f6a4a6ba2487a7a3729332628b15a32 100644 (file)
 #define IDC_DISPLAY_BUFFERCNT           1028
 #define IDC_PORT0_JOYSMODE              1029
 #define IDC_SCREENMODE_NATIVE2          1029
+#define IDC_FASTMEM2                    1029
 #define IDC_SLOWMEM                     1030
 #define IDC_PORT1_JOYSMODE              1030
 #define IDC_SCREENMODE_RTG2             1030
 #define IDC_CHIPRAM                     1045
 #define IDC_SLOWRAM                     1046
 #define IDC_Z3TEXT                      1047
+#define IDC_FASTRAM2                    1047
 #define IDC_Z3FASTRAM                   1048
 #define IDC_Z3FASTMEM                   1049
 #define IDC_MBRAM1                      1050
 #define IDC_HDF_CONTROLLER              1504
 #define IDC_RESETAMIGA                  1504
 #define IDC_QUITEMU                     1505
+#define IDC_HDF_CONTROLLER_UNIT         1505
 #define IDC_MAPDRIVES                   1507
 #define IDC_CPUTEXT                     1508
 #define IDC_MAPDRIVES_NET               1508
 #define IDC_CACHETEXT                   1509
 #define IDC_SWAP                        1509
 #define IDC_MAPDRIVES_CD                1509
-#define IDC_RESTARTEMU2                 1509
 #define IDC_ERRORLOG                    1509
 #define IDC_SELECTRESTEXT               1510
 #define IDC_FLUSHPRINTER                1510
 #define IDC_CS_RESETWARNING2            1752
 #define IDC_CS_CIATODBUG                1752
 #define IDC_DBG_MEMINPUT                1753
+#define IDC_CS_Z3AUTOCONFIG             1753
 #define IDC_DBG_MEMDOWN                 1754
 #define IDC_DBG_MEMUP                   1755
 #define IDC_DBG_MEM                     1756
 #define IDC_ASSOCIATE_ON                1792
 #define IDC_DD_SURFACETYPE2             1792
 #define IDC_DXMODE                      1792
+#define IDC_REGISTRYMODE                1792
 #define IDC_RTG_VBLANKRATE              1793
 #define IDC_DF0WPTEXTQ                  1793
 #define IDC_WINDOWEDMODE                1793
 #define IDC_CD_SELECT                   1807
 #define IDC_FASTMEMAUTOCONFIG           1808
 #define IDC_RTG_DISPLAYSELECT           1809
+#define IDC_Z3REALMAPPING               1809
 #define IDC_MISCLIST                    1810
 #define IDC_STATENAME                   1811
 #define IDC_SAMPLER_STEREO              1812
index a3efc44b37b8e224ce60817599917c22e40ac363..099c1d621ce37aea718797c9996a2191579544f2 100644 (file)
@@ -102,11 +102,11 @@ BEGIN
     LTEXT           "Real Time Clock file",IDC_STATIC,12,174,313,15,SS_CENTERIMAGE
     EDITTEXT        IDC_RTCFILE,12,191,361,12,ES_AUTOHSCROLL
     PUSHBUTTON      "...",IDC_RTCCHOOSER,376,189,10,15
-    COMBOBOX        IDC_A2091ROMFILE,12,222,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_A2091ROMFILE,12,223,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_A2091ROMCHOOSER,187,221,10,15
     LTEXT           "A590/A2091 SCSI ROM file:",IDC_STATIC,12,207,170,15,SS_CENTERIMAGE
     LTEXT           "A4091 SCSI ROM file:",IDC_STATIC,203,207,170,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_A4091ROMFILE,202,222,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_A4091ROMFILE,202,223,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_A4091ROMCHOOSER,376,221,10,15
 END
 
@@ -170,7 +170,7 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,154,124,10
 END
 
-IDD_MEMORY DIALOGEX 0, 0, 396, 206
+IDD_MEMORY DIALOGEX 0, 0, 396, 242
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 EXSTYLE WS_EX_CONTEXTHELP
 FONT 8, "MS Sans Serif", 0, 0, 0x1
@@ -179,10 +179,10 @@ BEGIN
     RTEXT           "Chip:",IDC_STATIC,7,25,60,15,SS_CENTERIMAGE
     CONTROL         "Slider1",IDC_CHIPMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,68,22,60,20
     EDITTEXT        IDC_CHIPRAM,135,25,40,12,ES_CENTER | ES_READONLY
-    RTEXT           "Fast:",IDC_STATIC,8,49,60,15,SS_CENTERIMAGE
+    RTEXT           "Z2 Fast:",IDC_STATIC,8,49,60,15,SS_CENTERIMAGE
     CONTROL         "Slider1",IDC_FASTMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,68,47,60,20
     EDITTEXT        IDC_FASTRAM,135,53,40,12,ES_CENTER | ES_READONLY
-    CONTROL         "Autoconfig Fast RAM",IDC_FASTMEMAUTOCONFIG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,51,76,124,10
+    CONTROL         "Autoconfig Z2 Fast RAM",IDC_FASTMEMAUTOCONFIG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,220,120,10
     RTEXT           "Slow:",IDC_STATIC,179,25,66,15,SS_CENTERIMAGE
     CONTROL         "Slider1",IDC_SLOWMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,248,22,60,20
     EDITTEXT        IDC_SLOWRAM,311,25,40,12,ES_CENTER | ES_READONLY
@@ -193,13 +193,18 @@ BEGIN
     CONTROL         "",IDC_Z3CHIPMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,248,71,60,20
     EDITTEXT        IDC_Z3CHIPRAM,311,76,40,12,ES_CENTER | ES_READONLY
     EDITTEXT        IDC_MAX32RAM,14,99,366,12,ES_CENTER | ES_READONLY
-    GROUPBOX        "A3000/A4000 Advanced Memory Settings",IDC_STATIC,1,131,393,65
-    RTEXT           "Motherboard Fast:",IDC_STATIC,44,149,129,10,SS_CENTERIMAGE
-    CONTROL         "",IDC_MBMEM1,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,177,145,60,20
-    EDITTEXT        IDC_MBRAM1,240,148,40,12,ES_CENTER | ES_READONLY
-    RTEXT           "Processor Slot Fast:",IDC_STATIC,44,172,129,10,SS_CENTERIMAGE
-    CONTROL         "",IDC_MBMEM2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,177,168,60,20
-    EDITTEXT        IDC_MBRAM2,240,171,40,12,ES_CENTER | ES_READONLY
+    GROUPBOX        "Advanced Memory Settings",IDC_STATIC,0,130,393,109
+    RTEXT           "Motherboard Fast:",IDC_STATIC,14,149,129,10,SS_CENTERIMAGE
+    CONTROL         "",IDC_MBMEM1,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,149,145,68,20
+    EDITTEXT        IDC_MBRAM1,224,148,40,12,ES_CENTER | ES_READONLY
+    RTEXT           "Processor Slot Fast:",IDC_STATIC,14,172,129,10,SS_CENTERIMAGE
+    CONTROL         "",IDC_MBMEM2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,149,168,68,20
+    EDITTEXT        IDC_MBRAM2,224,171,40,12,ES_CENTER | ES_READONLY
+    CONTROL         "",IDC_FASTMEM2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,149,193,68,20
+    EDITTEXT        IDC_FASTRAM2,224,196,40,12,ES_CENTER | ES_READONLY
+    RTEXT           "Second Z2 Fast RAM board:",IDC_STATIC,27,194,116,15,SS_CENTERIMAGE
+    CONTROL         "JIT Direct compatible Z3 memory mapping",IDC_Z3REALMAPPING,
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,220,186,10
 END
 
 IDD_CPU DIALOGEX 0, 0, 396, 283
@@ -564,10 +569,10 @@ FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
     GROUPBOX        "Settings",IDC_STATIC,2,2,392,164
     RTEXT           "Path:",IDC_HARDFILE_DIR_TEXT,10,18,37,10
-    EDITTEXT        IDC_PATH_NAME,52,15,325,15,ES_AUTOHSCROLL
+    COMBOBOX        IDC_PATH_NAME,52,15,325,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_SELECTOR,380,14,11,15
     RTEXT           "FileSys:",IDC_HARDFILE_FILESYS_TEXT,13,38,34,10
-    EDITTEXT        IDC_PATH_FILESYS,52,35,325,15,ES_AUTOHSCROLL
+    COMBOBOX        IDC_PATH_FILESYS,51,35,325,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_FILESYS_SELECTOR,380,34,11,15
     RTEXT           "Device:",IDC_HARDFILE_DEVICE_TEXT,16,58,31,10
     EDITTEXT        IDC_HARDFILE_DEVICE,52,55,121,15,ES_AUTOHSCROLL
@@ -576,18 +581,18 @@ BEGIN
     CONTROL         "Bootable",IDC_HDF_AUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,74,67,10
     CONTROL         "Do not mount",IDC_HDF_DONOTMOUNT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,217,74,67,10
     CONTROL         "Global filesystem",IDC_HDF_ADDFSRES,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,298,74,82,10
-    RTEXT           "Boot priority:",IDC_HARDFILE_BOOTPRI_TEXT,26,94,78,10
-    EDITTEXT        IDC_HARDFILE_BOOTPRI,109,90,44,15
-    RTEXT           "Surfaces:",IDC_SURFACES_TEXT,160,94,48,10
-    EDITTEXT        IDC_HEADS,213,90,40,15,ES_NUMBER
-    RTEXT           "Reserved:",IDC_RESERVED_TEXT,262,94,50,10
-    EDITTEXT        IDC_RESERVED,317,90,40,15,ES_NUMBER
-    RTEXT           "HD Controller:",IDC_STATIC,26,113,78,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_HDF_CONTROLLER,109,112,44,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    RTEXT           "Sectors:",IDC_SECTORS_TEXT,160,113,48,10
-    EDITTEXT        IDC_SECTORS,213,111,40,15,ES_NUMBER
-    RTEXT           "Block size:",IDC_BLOCKSIZE_TEXT,261,113,50,10
-    EDITTEXT        IDC_BLOCKSIZE,317,111,40,15,ES_NUMBER
+    RTEXT           "Boot priority:",IDC_HARDFILE_BOOTPRI_TEXT,67,94,83,10
+    EDITTEXT        IDC_HARDFILE_BOOTPRI,155,90,44,15
+    RTEXT           "Surfaces:",IDC_SURFACES_TEXT,209,94,48,10
+    EDITTEXT        IDC_HEADS,262,90,40,15,ES_NUMBER
+    RTEXT           "Reserved:",IDC_RESERVED_TEXT,307,94,50,10
+    EDITTEXT        IDC_RESERVED,362,90,28,15,ES_NUMBER
+    RTEXT           "HD Controller:",IDC_STATIC,11,113,54,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_HDF_CONTROLLER,73,112,93,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    RTEXT           "Sectors:",IDC_SECTORS_TEXT,209,113,48,10
+    EDITTEXT        IDC_SECTORS,262,111,40,15,ES_NUMBER
+    RTEXT           "Block size:",IDC_BLOCKSIZE_TEXT,306,113,50,10
+    EDITTEXT        IDC_BLOCKSIZE,362,111,28,15,ES_NUMBER
     EDITTEXT        IDC_HDFINFO,5,131,385,12,ES_CENTER | ES_READONLY
     EDITTEXT        IDC_HDFINFO2,5,147,385,12,ES_CENTER | ES_READONLY
     GROUPBOX        "New hard disk image file",IDC_STATIC,2,171,392,62
@@ -601,6 +606,7 @@ BEGIN
     CONTROL         "Dynamic HDF",IDC_HF_DYNAMIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,280,208,87,10
     PUSHBUTTON      "OK",IDOK,147,242,50,14
     PUSHBUTTON      "Cancel",IDCANCEL,203,242,50,14
+    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,173,112,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_FILESYS DIALOGEX 15, 25, 396, 111
@@ -613,11 +619,11 @@ BEGIN
     RTEXT           "Volume label:",-1,6,28,63,10
     EDITTEXT        IDC_VOLUME_NAME,73,25,104,15,ES_AUTOHSCROLL
     RTEXT           "Path:",-1,5,49,64,10
-    EDITTEXT        IDC_PATH_NAME,73,45,315,17,ES_AUTOHSCROLL
+    COMBOBOX        IDC_PATH_NAME,73,46,315,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     CONTROL         "Read/write",IDC_FS_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,259,7,67,10
     CONTROL         "Bootable",IDC_FS_AUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,7,56,10
-    RTEXT           "Boot priority:",IDC_VOLUME_BOOTPRI_TEXT,276,28,49,8
-    EDITTEXT        IDC_VOLUME_BOOTPRI,336,25,30,15
+    RTEXT           "Boot priority:",IDC_VOLUME_BOOTPRI_TEXT,298,28,49,8
+    EDITTEXT        IDC_VOLUME_BOOTPRI,358,25,30,15
     PUSHBUTTON      "Select Directory",IDC_FS_SELECT_DIR,72,66,123,15
     PUSHBUTTON      "Select Archive or Plain File",IDC_FS_SELECT_FILE,197,66,123,15
     PUSHBUTTON      "OK",IDOK,72,90,62,15
@@ -726,6 +732,7 @@ BEGIN
     CONTROL         "Denise/Lisa revision:",IDC_CS_DENISE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,275,107,11
     EDITTEXT        IDC_CS_AGNUSREV,311,260,45,13,ES_AUTOHSCROLL
     EDITTEXT        IDC_CS_DENISEREV,311,275,45,13,ES_AUTOHSCROLL
+    CONTROL         "Z3 Autoconfig",IDC_CS_Z3AUTOCONFIG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,184,104,11
 END
 
 IDD_AVIOUTPUT DIALOGEX 0, 0, 396, 260
@@ -845,12 +852,13 @@ BEGIN
     EDITTEXT        IDC_HDFINFO,5,29,385,12,ES_CENTER | ES_READONLY
     EDITTEXT        IDC_HDFINFO2,5,46,385,12,ES_CENTER | ES_READONLY
     DEFPUSHBUTTON   "Create hard disk image file",IDC_HARDDRIVE_IMAGE,49,67,115,14
-    EDITTEXT        IDC_PATH_NAME,183,67,97,15,ES_AUTOHSCROLL | NOT WS_VISIBLE
-    RTEXT           "HD Controller:",IDC_STATIC,12,90,65,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_HDF_CONTROLLER,91,89,61,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "Read/write",IDC_HDF_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,172,90,60,10
+    EDITTEXT        IDC_PATH_NAME,188,67,97,15,ES_AUTOHSCROLL | NOT WS_VISIBLE
+    RTEXT           "HD Controller:",IDC_STATIC,16,90,56,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_HDF_CONTROLLER,80,89,92,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Read/write",IDC_HDF_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,315,71,60,10
     DEFPUSHBUTTON   "Add hard drive",IDOK,236,87,73,14
     PUSHBUTTON      "Cancel",IDCANCEL,316,87,73,14
+    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,179,89,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_MISC2 DIALOGEX 0, 0, 396, 263
@@ -938,7 +946,7 @@ BEGIN
     PUSHBUTTON      "Clear disk history",IDC_RESETDISKHISTORY,99,229,92,14
     COMBOBOX        IDC_PATHS_DEFAULTTYPE,99,213,163,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Clear registry",IDC_RESETREGISTRY,302,212,92,14
-    CONTROL         "Use relative paths",IDC_PATHS_RELATIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,199,231,189,11
+    CONTROL         "Use relative paths",IDC_PATHS_RELATIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,199,231,94,11
     EDITTEXT        IDC_LOGPATH,7,281,324,13,ES_READONLY
     PUSHBUTTON      "Open [] Open selected file.",IDC_LOGOPEN,337,280,51,14
     COMBOBOX        IDC_LOGSELECT,7,263,137,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
@@ -946,6 +954,7 @@ BEGIN
     PUSHBUTTON      "Save All [] Save and open both logs and config file.",IDC_LOGSAVE,337,264,51,14
     GROUPBOX        "Debug logging",IDC_STATIC,1,248,393,53
     CONTROL         "Log window",IDC_LOGENABLE2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,254,264,68,12
+    CONTROL         "Portable mode",IDC_REGISTRYMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,303,231,82,11
 END
 
 IDD_QUICKSTART DIALOGEX 0, 0, 396, 262
@@ -1156,11 +1165,12 @@ STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK |
 CAPTION "CD Settings"
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
-    RTEXT           "HD Controller:",IDC_STATIC,12,90,65,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_HDF_CONTROLLER,91,89,61,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    DEFPUSHBUTTON   "Add CD Drive",IDOK,236,87,73,14
-    PUSHBUTTON      "Cancel",IDCANCEL,316,87,73,14
+    RTEXT           "HD Controller:",IDC_STATIC,7,90,65,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_HDF_CONTROLLER,83,89,100,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    DEFPUSHBUTTON   "Add CD Drive",IDOK,236,89,73,14
+    PUSHBUTTON      "Cancel",IDCANCEL,316,89,73,14
     CONTROL         "",IDC_CDLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,4,4,387,77
+    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,189,89,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_TAPEDRIVE DIALOGEX 0, 0, 395, 80
@@ -1169,14 +1179,15 @@ CAPTION "Tape Drive Settings"
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
     RTEXT           "Path:",IDC_STATIC,4,18,43,10,SS_CENTERIMAGE
-    EDITTEXT        IDC_PATH_NAME,52,15,334,15,ES_AUTOHSCROLL
     PUSHBUTTON      "Select Directory",IDC_TAPE_SELECT_DIR,19,36,123,15
     PUSHBUTTON      "Select Archive or Plain File",IDC_TAPE_SELECT_FILE,160,36,123,15
     CONTROL         "Read/write",IDC_TAPE_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,313,39,67,10
-    RTEXT           "HD Controller:",IDC_STATIC,35,61,65,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_HDF_CONTROLLER,115,59,61,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    DEFPUSHBUTTON   "Add Tape Drive",IDOK,201,58,88,14
-    PUSHBUTTON      "Cancel",IDCANCEL,300,58,87,14
+    RTEXT           "HD Controller:",IDC_STATIC,7,61,65,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_HDF_CONTROLLER,79,59,100,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    DEFPUSHBUTTON   "Add Tape Drive",IDOK,223,58,88,14
+    PUSHBUTTON      "Cancel",IDCANCEL,318,58,67,14
+    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,186,59,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_PATH_NAME,52,15,332,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_DISKINFO DIALOGEX 0, 0, 491, 323
@@ -1196,8 +1207,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,8,1,0
- PRODUCTVERSION 2,8,1,0
+ FILEVERSION 2,8,2,0
+ PRODUCTVERSION 2,8,2,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -1213,12 +1224,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "2.8.1.0"
+            VALUE "FileVersion", "2.8.2.0"
             VALUE "InternalName", "WinUAE"
             VALUE "LegalCopyright", "© 1996-2014 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "2.8.1.0"
+            VALUE "ProductVersion", "2.8.2.0"
         END
     END
     BLOCK "VarFileInfo"
@@ -1344,7 +1355,6 @@ GUIDELINES DESIGNINFO
 BEGIN
     IDD_KICKSTART, DIALOG
     BEGIN
-        BOTTOMMARGIN, 217
     END
 
     IDD_DISPLAY, DIALOG
@@ -1353,6 +1363,7 @@ BEGIN
 
     IDD_MEMORY, DIALOG
     BEGIN
+        BOTTOMMARGIN, 239
     END
 
     IDD_CPU, DIALOG
@@ -1739,7 +1750,7 @@ BEGIN
     IDS_DEFAULT_HOST        "Default Configuration"
     IDS_SOUND_4CHANNEL      "4 Channels"
     IDS_HF_FS_CUSTOM        "Custom"
-    IDS_SELECTFS            "Select file system handler (FastFileSystem, SmartFilesystem, etc.)"
+    IDS_SELECTFS            "Select file system handler (FFS, PFS, SFS, etc.)"
     IDS_KEYJOY              "Keyboard Layout A (Numeric keypad, 0 and 5 = Fire)\nKeyboard Layout B (Cursor keys, Right CTRL and ALT = Fire)\nKeyboard Layout C (W=Up S=Down A=Left D=Right, Left ALT = Fire)\nX-Arcade (Left)\nX-Arcade (Right)"
     IDS_STATEFILE_UNCOMPRESSED "Uncompressed"
     IDS_STATEFILE_RAMDUMP   "RAM dump"
index 863389edbd62a9006487b9f0231c65cb991e6acd..e1c1f3da7023267be5f3927c4c1474c868f5fb94 100644 (file)
@@ -1322,12 +1322,12 @@ static int gethdnum (int n)
 {
        struct uaedev_config_data *uci = &currprefs.mountconfig[n];
        int num = -1;
-       if (uci->ci.controller == HD_CONTROLLER_UAE) {
+       if (uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE) {
                num = n;
-       } else if (uci->ci.controller <= HD_CONTROLLER_IDE3 ) {
-               num = uci->ci.controller - HD_CONTROLLER_IDE0;
-       } else if (uci->ci.controller <= HD_CONTROLLER_SCSI6) {
-               num = uci->ci.controller - HD_CONTROLLER_SCSI0;
+       } else if (uci->ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && uci->ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST) {
+               num = uci->ci.controller_unit;
+       } else if (uci->ci.controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && uci->ci.controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST) {
+               num = uci->ci.controller_unit;
        }
        return num;
 }
index c3c0f03ad01cb8d541012bf1ca247c72010c394e..c6cccfa27b031901f16620968a88f635bd413ddc 100644 (file)
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
-#define LANG_DLL_FULL_VERSION_MATCH 0
+#define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("8")
+#define WINUAEBETA _T("1")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2014, 6, 18)
+#define WINUAEDATE MAKEBD(2014, 7, 3)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index a2ed426d828972c76281b6e49af7742e25c380c4..4f7360d99e4876bcf74db4c793e35760782e7a7c 100644 (file)
@@ -195,7 +195,7 @@ static TCHAR quickstart_cddrive[16];
 static int quickstart_ok, quickstart_ok_floppy;
 static void addfloppytype (HWND hDlg, int n);
 static void addfloppyhistory (HWND hDlg);
-static void addfloppyhistory_2 (HWND hDlg, int n, int f_text, int type);
+static void addhistorymenu (HWND hDlg, const TCHAR*, int f_text, int type, bool manglepath);
 static void addcdtype (HWND hDlg, int id);
 static void getfloppyname (HWND hDlg, int n, int cd, int f_text);
 
@@ -557,17 +557,30 @@ int DirectorySelection (HWND hDlg, const GUID *guid, TCHAR *path)
        return val;
 }
 
+static const TCHAR *historytypes[] =
+{
+       _T("DiskImageMRUList"),
+       _T("CDImageMRUList"),
+       _T("DirFileSysMRUList"),
+       _T("HardfileMRUList"),
+       _T("FileSysMRUList"),
+       _T("TapeImageMRUList")
+};
+static int regread;
+
 static void write_disk_history2 (int type)
 {
        int i, j;
        TCHAR tmp[16];
        UAEREG *fkey;
 
-       fkey = regcreatetree (NULL, type ? _T("CDImageMRUList") : _T("DiskImageMRUList"));
+       if (!(regread & (1 << type)))
+               return;
+       fkey = regcreatetree (NULL, historytypes[type]);
        if (fkey == NULL)
                return;
        j = 1;
-       for (i = 0; i <= MAX_PREVIOUS_FLOPPIES; i++) {
+       for (i = 0; i <= MAX_PREVIOUS_IMAGES; i++) {
                TCHAR *s = DISK_history_get (i, type);
                if (s == 0 || _tcslen (s) == 0)
                        continue;
@@ -575,7 +588,7 @@ static void write_disk_history2 (int type)
                regsetstr (fkey, tmp, s);
                j++;
        }
-       while (j <= MAX_PREVIOUS_FLOPPIES) {
+       while (j <= MAX_PREVIOUS_IMAGES) {
                TCHAR *s = _T("");
                _stprintf (tmp, _T("Image%02d"), j);
                regsetstr (fkey, tmp, s);
@@ -587,29 +600,39 @@ void write_disk_history (void)
 {
        write_disk_history2 (HISTORY_FLOPPY);
        write_disk_history2 (HISTORY_CD);
+       write_disk_history2 (HISTORY_DIR);
+       write_disk_history2 (HISTORY_HDF);
+       write_disk_history2 (HISTORY_FS);
+       write_disk_history2 (HISTORY_TAPE);
 }
 
 void reset_disk_history (void)
 {
-       int i;
+       int i, rrold;
 
-       for (i = 0; i < MAX_PREVIOUS_FLOPPIES; i++) {
+       for (i = 0; i < MAX_PREVIOUS_IMAGES; i++) {
                DISK_history_add (NULL, i, HISTORY_FLOPPY, 0);
                DISK_history_add (NULL, i, HISTORY_CD, 0);
+               DISK_history_add (NULL, i, HISTORY_DIR, 0);
+               DISK_history_add (NULL, i, HISTORY_HDF, 0);
+               DISK_history_add (NULL, i, HISTORY_FS, 0);
+               DISK_history_add (NULL, i, HISTORY_TAPE, 0);
        }
+       rrold = regread;
+       regread = (1 << HISTORY_MAX) - 1;
        write_disk_history ();
+       regread = rrold;
 }
 
 UAEREG *read_disk_history (int type)
 {
-       static int regread;
-       TCHAR tmp2[1000];
+       TCHAR tmp2[MAX_DPATH];
        int size, size2;
        int idx, idx2;
        UAEREG *fkey;
-       TCHAR tmp[1000];
+       TCHAR tmp[MAX_DPATH];
 
-       fkey = regcreatetree (NULL, type ? _T("CDImageMRUList") : _T("DiskImageMRUList"));
+       fkey = regcreatetree (NULL, historytypes[type]);
        if (fkey == NULL || (regread & (1 << type)))
                return fkey;
 
@@ -622,7 +645,7 @@ UAEREG *read_disk_history (int type)
                if (_tcslen (tmp) == 7) {
                        idx2 = _tstol (tmp + 5) - 1;
                        if (idx2 >= 0)
-                               DISK_history_add (tmp2, idx2, type, TRUE);
+                               DISK_history_add (tmp2, idx2, type, type != HISTORY_FLOPPY && type != HISTORY_CD);
                }
                idx++;
        }
@@ -1208,16 +1231,76 @@ static int drag_move (HWND hWnd, LPARAM lParam)
 
 static HWND cachedlist = NULL;
 
+static const TCHAR *memsize_names[] = {
+       /* 0 */ szNone.c_str(),
+       /* 1 */ _T("64 KB"),
+       /* 2 */ _T("128 KB"),
+       /* 3 */ _T("256 KB"),
+       /* 4 */ _T("512 KB"),
+       /* 5 */ _T("1 MB"),
+       /* 6 */ _T("2 MB"),
+       /* 7 */ _T("4 MB"),
+       /* 8 */ _T("8 MB"),
+       /* 9 */ _T("16 MB"),
+       /* 10*/ _T("32 MB"),
+       /* 11*/ _T("64 MB"),
+       /* 12*/ _T("128 MB"),
+       /* 13*/ _T("256 MB"),
+       /* 14*/ _T("512 MB"),
+       /* 15*/ _T("1 GB"),
+       /* 16*/ _T("1.5MB"),
+       /* 17*/ _T("1.8MB"),
+       /* 18*/ _T("2 GB"),
+       /* 19*/ _T("384 MB"),
+       /* 20*/ _T("768 MB"),
+       /* 21*/ _T("1.5 GB"),
+       /* 22*/ _T("2.5 GB"),
+       /* 23*/ _T("3 GB")
+};
+
+static unsigned long memsizes[] = {
+       /* 0 */ 0,
+       /* 1 */ 0x00010000, /*  64K */
+       /* 2 */ 0x00020000, /* 128K */
+       /* 3 */ 0x00040000, /* 256K */
+       /* 4 */ 0x00080000, /* 512K */
+       /* 5 */ 0x00100000, /* 1M */
+       /* 6 */ 0x00200000, /* 2M */
+       /* 7 */ 0x00400000, /* 4M */
+       /* 8 */ 0x00800000, /* 8M */
+       /* 9 */ 0x01000000, /* 16M */
+       /* 10*/ 0x02000000, /* 32M */
+       /* 11*/ 0x04000000, /* 64M */
+       /* 12*/ 0x08000000, //128M
+       /* 13*/ 0x10000000, //256M
+       /* 14*/ 0x20000000, //512M
+       /* 15*/ 0x40000000, //1GB
+       /* 16*/ 0x00180000, //1.5MB
+       /* 17*/ 0x001C0000, //1.8MB
+       /* 18*/ 0x80000000, //2GB
+       /* 19*/ 0x18000000, //384M
+       /* 20*/ 0x30000000, //768M
+       /* 21*/ 0x60000000, //1.5GB
+       /* 22*/ 0xA8000000, //2.5GB
+       /* 23*/ 0xC0000000, //3GB
+};
+
+static int msi_chip[] = { 3, 4, 5, 16, 6, 7, 8 };
+static int msi_bogo[] = { 0, 4, 5, 16, 17 };
+static int msi_fast[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
+static int msi_z3fast[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 19, 14, 20, 15, 21, 18, 22, 23 };
+static int msi_z3chip[] = { 0, 9, 10, 11, 12, 13, 19, 14, 20, 15 };
+static int msi_gfx[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
 #define MIN_CHIP_MEM 0
 #define MAX_CHIP_MEM 6
 #define MIN_FAST_MEM 0
-#define MAX_FAST_MEM 4
+#define MAX_FAST_MEM 8
 #define MIN_SLOW_MEM 0
 #define MAX_SLOW_MEM 4
 #define MIN_Z3_MEM 0
-//#define MAX_Z3_MEM ((max_z3fastmem >> 20) < 512 ? 12 : ((max_z3fastmem >> 20) < 1024 ? 13 : ((max_z3fastmem >> 20) < 2048) ? 14 : ((max_z3fastmem >> 20) < 2560) ? 15 : ((max_z3fastmem >> 20) < 3072) ? 16 : 17))
 #define MAX_Z3_MEM ((max_z3fastmem >> 20) < 512 ? 12 : ((max_z3fastmem >> 20) < 1024 ? 13 : ((max_z3fastmem >> 20) < 2048) ? 14 : 15))
-#define MAX_Z3_CHIPMEM 7
+#define MAX_Z3_CHIPMEM 9
 #define MIN_P96_MEM 0
 #define MAX_P96_MEM_Z3 ((max_z3fastmem >> 20) < 512 ? 8 : ((max_z3fastmem >> 20) < 1024 ? 9 : ((max_z3fastmem >> 20) < 2048) ? 10 : 11))
 #define MAX_P96_MEM_Z2 4
@@ -2728,63 +2811,6 @@ static BOOL CreateHardFile (HWND hDlg, UINT hfsizem, TCHAR *dostype, TCHAR *newp
        return result;
 }
 
-static const TCHAR *memsize_names[] = {
-       /* 0 */ szNone.c_str(),
-       /* 1 */ _T("256 K"),
-       /* 2 */ _T("512 K"),
-       /* 3 */ _T("1 MB"),
-       /* 4 */ _T("2 MB"),
-       /* 5 */ _T("4 MB"),
-       /* 6 */ _T("8 MB"),
-       /* 7 */ _T("16 MB"),
-       /* 8 */ _T("32 MB"),
-       /* 9 */ _T("64 MB"),
-       /* 10*/ _T("128 MB"),
-       /* 11*/ _T("256 MB"),
-       /* 12*/ _T("512 MB"),
-       /* 13*/ _T("1 GB"),
-       /* 14*/ _T("1.5MB"),
-       /* 15*/ _T("1.8MB"),
-       /* 16*/ _T("2 GB"),
-       /* 17*/ _T("384 MB"),
-       /* 18*/ _T("768 MB"),
-       /* 19*/ _T("1.5 GB"),
-       /* 20*/ _T("2.5 GB"),
-       /* 21*/ _T("3 GB")
-};
-
-static unsigned long memsizes[] = {
-       /* 0 */ 0,
-       /* 1 */ 0x00040000, /* 256K */
-       /* 2 */ 0x00080000, /* 512K */
-       /* 3 */ 0x00100000, /* 1M */
-       /* 4 */ 0x00200000, /* 2M */
-       /* 5 */ 0x00400000, /* 4M */
-       /* 6 */ 0x00800000, /* 8M */
-       /* 7 */ 0x01000000, /* 16M */
-       /* 8 */ 0x02000000, /* 32M */
-       /* 9 */ 0x04000000, /* 64M */
-       /* 10*/ 0x08000000, //128M
-       /* 11*/ 0x10000000, //256M
-       /* 12*/ 0x20000000, //512M
-       /* 13*/ 0x40000000, //1GB
-       /* 14*/ 0x00180000, //1.5MB
-       /* 15*/ 0x001C0000, //1.8MB
-       /* 16*/ 0x80000000, //2GB
-       /* 17*/ 0x18000000, //384M
-       /* 18*/ 0x30000000, //768M
-       /* 19*/ 0x60000000, //1.5GB
-       /* 20*/ 0xA8000000, //2.5GB
-       /* 21*/ 0xC0000000, //3GB
-};
-
-static int msi_chip[] = { 1, 2, 3, 14, 4, 5, 6 };
-static int msi_bogo[] = { 0, 2, 3, 14, 15 };
-static int msi_fast[] = { 0, 3, 4, 5, 6 };
-static int msi_z3fast[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 12, 18, 13, 19, 16, 20, 21 };
-static int msi_z3chip[] = { 0, 7, 8, 9, 10, 11, 12, 13 };
-static int msi_gfx[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
-
 static int CalculateHardfileSize (HWND hDlg)
 {
        BOOL Translated = FALSE;
@@ -4141,7 +4167,7 @@ void InitializeListView (HWND hDlg)
                {
                        struct uaedev_config_data *uci = &workprefs.mountconfig[i];
                        struct uaedev_config_info *ci = &uci->ci;
-                       int nosize = 0, type;
+                       int nosize = 0, type, ctype;
                        struct mountedinfo mi;
                        TCHAR *rootdir, *rootdirp;
 
@@ -4172,24 +4198,35 @@ void InitializeListView (HWND hDlg)
                        else
                                _stprintf (size_str, _T("%.1fM"), ((double)(uae_u32)(mi.size / (1024))) / 1024.0);
 
-                       if (ci->controller >= HD_CONTROLLER_IDE0 && ci->controller <= HD_CONTROLLER_IDE3) {
+                       ctype = ci->controller_type;
+                       if (ctype >= HD_CONTROLLER_TYPE_IDE_FIRST && ctype <= HD_CONTROLLER_TYPE_IDE_LAST) {
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
-                               _stprintf (devname_str, _T("*IDE%d*"), ci->controller - HD_CONTROLLER_IDE0);
+                               _stprintf (devname_str, _T("IDE:%d"), ci->controller_unit);
                                harddisktype (volname_str, ci);
                                _tcscpy (bootpri_str, _T("n/a"));
-                       } else if (ci->controller >= HD_CONTROLLER_SCSI0 && ci->controller <= HD_CONTROLLER_SCSI6) {
+                       } else if (ctype >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctype <= HD_CONTROLLER_TYPE_SCSI_LAST) {
+                               const TCHAR *scsidevs[] = {
+                                       _T("SCSI:%d"),
+                                       _T("A2091:%d"),
+                                       _T("A2091 2nd:%d"),
+                                       _T("A4091:%d"),
+                                       _T("A4091 2nd:%d"),
+                                       _T("A3000:%d"),
+                                       _T("A4000T:%d"),
+                                       _T("CDTV:%d")
+                               };
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
-                               _stprintf (devname_str, _T("*SCSI%d*"), ci->controller - HD_CONTROLLER_SCSI0);
+                               _stprintf (devname_str, scsidevs[ctype - HD_CONTROLLER_TYPE_SCSI_FIRST], ci->controller_unit);
                                harddisktype (volname_str, ci);
                                _tcscpy (bootpri_str, _T("n/a"));
-                       } else if (ci->controller == HD_CONTROLLER_PCMCIA_SRAM) {
+                       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
                                _tcscpy (blocksize_str, _T("n/a"));
-                               _tcscpy(devname_str, _T("*SRAM*"));
+                               _tcscpy(devname_str, _T("SRAM:0"));
                                _tcscpy (volname_str, _T("PCMCIA"));
                                _tcscpy (bootpri_str, _T("n/a"));
-                       } else if (ci->controller == HD_CONTROLLER_PCMCIA_IDE) {
+                       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
                                _tcscpy (blocksize_str, _T("n/a"));
-                               _tcscpy(devname_str, _T("*IDE*"));
+                               _tcscpy(devname_str, _T("IDE:0"));
                                _tcscpy (volname_str, _T("PCMCIA"));
                                _tcscpy (bootpri_str, _T("n/a"));
                        } else if (type == FILESYS_HARDFILE) {
@@ -4197,14 +4234,14 @@ void InitializeListView (HWND hDlg)
                                _tcscpy (devname_str, ci->devname);
                                _tcscpy (volname_str, _T("n/a"));
                                _stprintf (bootpri_str, _T("%d"), ci->bootpri);
-                       } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE || ci->controller) {
+                       } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE || ci->controller_type != HD_CONTROLLER_TYPE_UAE) {
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
-                               _tcscpy (devname_str, _T("*UAE*"));
+                               _tcscpy (devname_str, _T("UAE"));
                                _tcscpy (volname_str, _T("n/a"));
                                _tcscpy (bootpri_str, _T("n/a"));
                        } else if (type == FILESYS_TAPE) {
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
-                               _tcscpy (devname_str, _T("*UAE*"));
+                               _tcscpy (devname_str, _T("UAE"));
                                harddisktype (volname_str, ci);
                                _tcscpy (bootpri_str, _T("n/a"));
                        } else {
@@ -4227,7 +4264,7 @@ void InitializeListView (HWND hDlg)
 
                        lvstruct.mask     = LVIF_TEXT | LVIF_PARAM;
                        lvstruct.pszText  = mi.ismedia == false ? _T("E") : (nosize && mi.size >= 0 ? _T("X") : (mi.ismounted ? _T("*") : _T(" ")));
-                       if (ci->controller && mi.ismedia)
+                       if (ci->controller_type != HD_CONTROLLER_TYPE_UAE && mi.ismedia)
                                lvstruct.pszText = _T(" ");
                        lvstruct.lParam   = 0;
                        lvstruct.iItem    = i;
@@ -5175,6 +5212,8 @@ static INT_PTR CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                setac (hDlg, IDC_PATHS_RIP);
                CheckDlgButton(hDlg, IDC_PATHS_CONFIGCACHE, configurationcache);
                CheckDlgButton(hDlg, IDC_PATHS_RELATIVE, relativepaths);
+               CheckDlgButton(hDlg, IDC_REGISTRYMODE, getregmode() != 0);
+               ew(hDlg, IDC_REGISTRYMODE, FALSE);
                currentpage = PATHS_ID;
                ShowWindow (GetDlgItem (hDlg, IDC_RESETREGISTRY), FALSE);
                numtypes = 0;
@@ -5404,7 +5443,6 @@ static INT_PTR CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                relativepaths = ischecked (hDlg, IDC_PATHS_RELATIVE) ? 1 : 0;
                                regsetint (NULL, _T("RelativePaths"), relativepaths);
                                break;
-
                        }
                }
                recursive--;
@@ -7068,12 +7106,13 @@ static void values_to_chipsetdlg2 (HWND hDlg)
        CheckDlgButton (hDlg, IDC_CS_FATGARY, workprefs.cs_fatgaryrev >= 0);
        CheckDlgButton (hDlg, IDC_CS_AGNUS, workprefs.cs_agnusrev >= 0);
        CheckDlgButton (hDlg, IDC_CS_DENISE, workprefs.cs_deniserev >= 0);
-       CheckDlgButton (hDlg, IDC_CS_DMAC, workprefs.cs_mbdmac == 1);
-       CheckDlgButton (hDlg, IDC_CS_DMAC2, workprefs.cs_mbdmac == 2);
+       CheckDlgButton (hDlg, IDC_CS_DMAC, workprefs.cs_mbdmac & 1);
+       CheckDlgButton (hDlg, IDC_CS_DMAC2, workprefs.cs_mbdmac & 2);
        CheckDlgButton (hDlg, IDC_CS_CDTVSCSI, workprefs.cs_cdtvscsi);
        CheckDlgButton (hDlg, IDC_CS_PCMCIA, workprefs.cs_pcmcia);
        CheckDlgButton (hDlg, IDC_CS_SLOWISFAST, workprefs.cs_slowmemisfast);
        CheckDlgButton (hDlg, IDC_CS_CIATODBUG, workprefs.cs_ciatodbug);
+       CheckDlgButton (hDlg, IDC_CS_Z3AUTOCONFIG, workprefs.cs_z3autoconfig);
        CheckDlgButton (hDlg, IDC_CS_IDE1, workprefs.cs_ide > 0 && (workprefs.cs_ide & 1));
        CheckDlgButton (hDlg, IDC_CS_IDE2, workprefs.cs_ide > 0 && (workprefs.cs_ide & 2));
        txt[0] = 0;
@@ -7142,11 +7181,11 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        workprefs.cs_ramseyrev = ischecked (hDlg, IDC_CS_RAMSEY) ? 0x0f : -1;
        workprefs.cs_fatgaryrev = ischecked (hDlg, IDC_CS_FATGARY) ? 0x00 : -1;
        workprefs.cs_mbdmac = ischecked (hDlg, IDC_CS_DMAC) ? 1 : 0;
-       if (workprefs.cs_mbdmac == 0)
-               workprefs.cs_mbdmac = ischecked (hDlg, IDC_CS_DMAC2) ? 2 : 0;
+       workprefs.cs_mbdmac |= ischecked (hDlg, IDC_CS_DMAC2) ? 2 : 0;
        workprefs.cs_cdtvscsi = ischecked (hDlg, IDC_CS_CDTVSCSI) ? 1 : 0;
        workprefs.cs_pcmcia = ischecked (hDlg, IDC_CS_PCMCIA) ? 1 : 0;
        workprefs.cs_slowmemisfast = ischecked (hDlg, IDC_CS_SLOWISFAST) ? 1 : 0;
+       workprefs.cs_z3autoconfig = ischecked (hDlg, IDC_CS_Z3AUTOCONFIG) ? 1 : 0;
        workprefs.cs_ide = ischecked (hDlg, IDC_CS_IDE1) ? 1 : (ischecked (hDlg, IDC_CS_IDE2) ? 2 : 0);
        workprefs.cs_ciaatod = ischecked (hDlg, IDC_CS_CIAA_TOD1) ? 0
                : (ischecked (hDlg, IDC_CS_CIAA_TOD2) ? 1 : 2);
@@ -7218,6 +7257,7 @@ static void enable_for_chipsetdlg2 (HWND hDlg)
        ew (hDlg, IDC_CS_CIATODBUG, e);
        ew (hDlg, IDC_CS_NOEHB, e);
        ew (hDlg, IDC_CS_DIPAGNUS, e);
+       ew (hDlg, IDC_CS_Z3AUTOCONFIG, e);
        ew (hDlg, IDC_CS_KSMIRROR_E0, e);
        ew (hDlg, IDC_CS_KSMIRROR_A8, e);
        ew (hDlg, IDC_CS_CIAOVERLAY, e);
@@ -7262,7 +7302,7 @@ static INT_PTR CALLBACK ChipsetDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPA
 
 static void enable_for_memorydlg (HWND hDlg)
 {
-       int fast = workprefs.chipmem_size <= 0x200000;
+       int fast = true;
        int z3 = true;
 
 #ifndef AUTOCONFIG
@@ -7276,7 +7316,10 @@ static void enable_for_memorydlg (HWND hDlg)
        ew (hDlg, IDC_Z3CHIPMEM, z3);
        ew (hDlg, IDC_FASTMEM, fast);
        ew (hDlg, IDC_FASTRAM, fast);
+       ew (hDlg, IDC_FASTMEM2, fast);
+       ew (hDlg, IDC_FASTRAM2, fast);
        ew (hDlg, IDC_FASTMEMAUTOCONFIG, fast);
+       ew (hDlg, IDC_Z3REALMAPPING, z3);
        ew (hDlg, IDC_FASTTEXT, fast);
        ew (hDlg, IDC_GFXCARDTEXT, z3);
        ew (hDlg, IDC_MBRAM1, z3);
@@ -7289,18 +7332,23 @@ extern uae_u32 natmem_size;
 static void setmax32bitram (HWND hDlg)
 {
        TCHAR tmp[100];
-       uae_u32 size, rtgz3size;
+       uae_u32 size, rtgz3size, z3size;
+       uae_u32 sizealign = 16 * 1024 * 1024 - 1;
 
        rtgz3size = gfxboard_is_z3 (workprefs.rtgmem_type) ? workprefs.rtgmem_size : 0;
-       size = workprefs.z3fastmem_size + workprefs.z3fastmem2_size +
-               workprefs.z3chipmem_size + rtgz3size;
-       if (workprefs.z3chipmem_size && workprefs.z3fastmem_size)
-               size += 16 * 1024 * 1024;
-       if ((workprefs.z3fastmem_size || workprefs.z3chipmem_size) && rtgz3size)
+       size = ((workprefs.z3fastmem_size + sizealign) & ~sizealign) + ((workprefs.z3fastmem2_size + sizealign) & ~sizealign) +
+               ((rtgz3size + sizealign) & ~sizealign);
+       if (currprefs.a4091)
+               size += 2 * 16 * 1024 * 1024;
+       if (changed_prefs.mbresmem_high_size == 128 * 1024 * 1024 && (size || workprefs.z3chipmem_size))
                size += 16 * 1024 * 1024;
-
-       _stprintf (tmp, L"Total configured 32-bit RAM: %dM, reserved: %dM",
-               size / (1024 * 1024), (natmem_size - 256 * 1024 * 1024) / (1024 * 1024));
+       if (natmem_size > 0x40000000)
+               z3size = natmem_size - 0x40000000;
+       else
+               z3size = 0;
+       size += ((workprefs.z3chipmem_size + sizealign) & ~sizealign);
+       _stprintf (tmp, L"Configured 32-bit RAM: %dM, reserved: %dM, true Z3 address space available: %dM",
+               size / (1024 * 1024), (natmem_size - 256 * 1024 * 1024) / (1024 * 1024), z3size / (1024 * 1024));
        SetDlgItemText (hDlg, IDC_MAX32RAM, tmp);
 }
 
@@ -7339,15 +7387,35 @@ static void values_to_memorydlg (HWND hDlg)
        mem_size = 0;
        switch (workprefs.fastmem_size) {
        case 0x00000000: mem_size = 0; break;
-       case 0x00100000: mem_size = 1; break;
-       case 0x00200000: mem_size = 2; break;
-       case 0x00400000: mem_size = 3; break;
-       case 0x00800000: mem_size = 4; break;
-       case 0x01000000: mem_size = 5; break;
+       case 0x00010000: mem_size = 1; break;
+       case 0x00020000: mem_size = 2; break;
+       case 0x00040000: mem_size = 3; break;
+       case 0x00080000: mem_size = 4; break;
+       case 0x00100000: mem_size = 5; break;
+       case 0x00200000: mem_size = 6; break;
+       case 0x00400000: mem_size = 7; break;
+       case 0x00800000: mem_size = 8; break;
+       case 0x01000000: mem_size = 9; break;
        }
        SendDlgItemMessage (hDlg, IDC_FASTMEM, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_FASTRAM, memsize_names[msi_fast[mem_size]]);
 
+       mem_size = 0;
+       switch (workprefs.fastmem2_size) {
+       case 0x00000000: mem_size = 0; break;
+       case 0x00010000: mem_size = 1; break;
+       case 0x00020000: mem_size = 2; break;
+       case 0x00040000: mem_size = 3; break;
+       case 0x00080000: mem_size = 4; break;
+       case 0x00100000: mem_size = 5; break;
+       case 0x00200000: mem_size = 6; break;
+       case 0x00400000: mem_size = 7; break;
+       case 0x00800000: mem_size = 8; break;
+       case 0x01000000: mem_size = 9; break;
+       }
+       SendDlgItemMessage (hDlg, IDC_FASTMEM2, TBM_SETPOS, TRUE, mem_size);
+       SetDlgItemText (hDlg, IDC_FASTRAM2, memsize_names[msi_fast[mem_size]]);
+
        mem_size = 0;
        switch (workprefs.bogomem_size) {
        case 0x00000000: mem_size = 0; break;
@@ -7412,12 +7480,16 @@ static void values_to_memorydlg (HWND hDlg)
                mem_size = 3;
        else if (v < 0x10000000)
                mem_size = 4;
-       else if (v < 0x20000000)
+       else if (v < 0x18000000)
                mem_size = 5;
-       else if (v < 0x40000000)
+       else if (v < 0x20000000)
                mem_size = 6;
-       else
+       else if (v < 0x30000000)
                mem_size = 7;
+       else if (v < 0x40000000)
+               mem_size = 8;
+       else
+               mem_size = 9;
        int min_mem = MIN_P96_MEM;
        int max_mem = MAX_P96_MEM_Z3;
        if (!gfxboard_is_z3 (workprefs.rtgmem_type)) {
@@ -7566,8 +7638,16 @@ static void values_to_memorydlg (HWND hDlg)
 
 static void fix_values_memorydlg (void)
 {
-       if (workprefs.chipmem_size > 0x200000)
+       if (workprefs.chipmem_size <= 0x200000)
+               return;
+       if (workprefs.fastmem_size > 262144)
+               workprefs.fastmem_size = 262144;
+       if (workprefs.fastmem2_size > 262144)
+               workprefs.fastmem2_size = 262144;
+       if (workprefs.fastmem_size + workprefs.fastmem2_size > 262144) {
                workprefs.fastmem_size = 0;
+               workprefs.fastmem2_size = 0;
+       }
 }
 static void updatez3 (uae_u32 *size1p, uae_u32 *size2p)
 {
@@ -8023,16 +8103,19 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                currentpage = MEMORY_ID;
                SendDlgItemMessage (hDlg, IDC_CHIPMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_CHIP_MEM, MAX_CHIP_MEM));
                SendDlgItemMessage (hDlg, IDC_FASTMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_FAST_MEM, MAX_FAST_MEM));
+               SendDlgItemMessage (hDlg, IDC_FASTMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_FAST_MEM, MAX_FAST_MEM - 1));
                SendDlgItemMessage (hDlg, IDC_SLOWMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_SLOW_MEM, MAX_SLOW_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3FASTMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3CHIPMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_CHIPMEM));
                SendDlgItemMessage (hDlg, IDC_MBMEM1, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBL_MEM));
                SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBH_MEM));
                CheckDlgButton(hDlg, IDC_FASTMEMAUTOCONFIG, workprefs.fastmem_autoconfig);
+               CheckDlgButton(hDlg, IDC_Z3REALMAPPING, workprefs.jit_direct_compatible_memory);
 
 
        case WM_USER:
                workprefs.fastmem_autoconfig = ischecked (hDlg, IDC_FASTMEMAUTOCONFIG);
+               workprefs.jit_direct_compatible_memory = ischecked (hDlg, IDC_Z3REALMAPPING);
                fix_values_memorydlg ();
                values_to_memorydlg (hDlg);
                enable_for_memorydlg (hDlg);
@@ -8042,6 +8125,7 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        case WM_COMMAND:
                recursive++;
                workprefs.fastmem_autoconfig = ischecked (hDlg, IDC_FASTMEMAUTOCONFIG);
+               workprefs.jit_direct_compatible_memory = ischecked (hDlg, IDC_Z3REALMAPPING);
                recursive--;
                break;
 
@@ -8049,6 +8133,7 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                workprefs.chipmem_size = memsizes[msi_chip[SendMessage (GetDlgItem (hDlg, IDC_CHIPMEM), TBM_GETPOS, 0, 0)]];
                workprefs.bogomem_size = memsizes[msi_bogo[SendMessage (GetDlgItem (hDlg, IDC_SLOWMEM), TBM_GETPOS, 0, 0)]];
                workprefs.fastmem_size = memsizes[msi_fast[SendMessage (GetDlgItem (hDlg, IDC_FASTMEM), TBM_GETPOS, 0, 0)]];
+               workprefs.fastmem2_size = memsizes[msi_fast[SendMessage (GetDlgItem (hDlg, IDC_FASTMEM2), TBM_GETPOS, 0, 0)]];
                workprefs.z3fastmem_size = memsizes[msi_z3fast[SendMessage (GetDlgItem (hDlg, IDC_Z3FASTMEM), TBM_GETPOS, 0, 0)]];
                updatez3 (&workprefs.z3fastmem_size, &workprefs.z3fastmem2_size);
                workprefs.z3chipmem_size = memsizes[msi_z3chip[SendMessage (GetDlgItem (hDlg, IDC_Z3CHIPMEM), TBM_GETPOS, 0, 0)]];
@@ -9688,7 +9773,7 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf)
                for (i = 0; i < 16; i++) {
                        hdf_read_rdb (&hfd, id, i * 512, 512);
                        if (i == 0 && !memcmp (id + 2, "CIS", 3)) {
-                               hdf->ci.controller = HD_CONTROLLER_PCMCIA_SRAM;
+                               hdf->ci.controller_type = HD_CONTROLLER_TYPE_PCMCIA_SRAM;
                                break;
                        }
                        if (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) || (id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0)) {
@@ -9722,12 +9807,14 @@ static void default_tapedlg (struct tapedlg_vals *f)
 }
 static void default_hfdlg (struct hfdlg_vals *f, bool rdb)
 {
-       int ctrl = f->ci.controller;
+       int ctrl = f->ci.controller_type;
+       int unit = f->ci.controller_unit;
        memset (f, 0, sizeof (struct hfdlg_vals));
        uci_set_defaults (&f->ci, rdb);
        f->original = true;
        f->ci.type = UAEDEV_HDF;
-       f->ci.controller = ctrl;
+       f->ci.controller_type = ctrl;
+       f->ci.controller_unit = unit;
 }
 static void default_rdb_hfdlg (struct hfdlg_vals *f, const TCHAR *filename)
 {
@@ -9776,6 +9863,7 @@ static void volumeselectdir (HWND hDlg, int newdir)
                WIN32GUI_LoadUIString (IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH);
                if (DirectorySelection (hDlg, &volumeguid, directory_path)) {
                        newdir = 1;
+                       DISK_history_add (directory_path, -1, HISTORY_DIR, 1);
                        regsetstr (NULL, _T("FilesystemDirectoryPath"), directory_path);
                }
        }
@@ -9799,10 +9887,10 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                        else if (my_existsdir (current_fsvdlg.ci.rootdir))
                                archivehd = 0;
                        recursive++;
-                       setac (hDlg, IDC_PATH_NAME);
+                       setautocomplete (hDlg, IDC_PATH_NAME);
+                       addhistorymenu(hDlg, current_fsvdlg.ci.rootdir, IDC_PATH_NAME, HISTORY_DIR, false);
                        SetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.ci.volname);
                        SetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.ci.devname);
-                       SetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.ci.rootdir);
                        SetDlgItemInt (hDlg, IDC_VOLUME_BOOTPRI, current_fsvdlg.ci.bootpri, TRUE);
                        if (archivehd > 0)
                                current_fsvdlg.ci.readonly = true;
@@ -9886,7 +9974,7 @@ STATIC_INLINE bool is_hdf_rdb (void)
 static void sethardfile (HWND hDlg)
 {
        bool rdb = is_hdf_rdb ();
-       bool disables = !rdb || (rdb && current_hfdlg.ci.controller == HD_CONTROLLER_UAE);
+       bool disables = !rdb || (rdb && current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE);
 
        if (!disables)
                current_hfdlg.ci.bootpri = 0;
@@ -9906,28 +9994,43 @@ static void sethardfile (HWND hDlg)
        ew (hDlg, IDC_HDF_DONOTMOUNT, disables);
        hide (hDlg, IDC_HDF_AUTOBOOT, !disables);
        hide (hDlg, IDC_HDF_DONOTMOUNT, !disables);
-       hide (hDlg, IDC_HARDFILE_BOOTPRI, !disables);
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller, 0);
+       ew (hDlg, IDC_HARDFILE_BOOTPRI, disables);
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller_type, 0);
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
 }
 
-static void inithdcontroller (HWND hDlg)
+static void inithdcontroller (HWND hDlg, int ctype)
 {
        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_RESETCONTENT, 0, 0);
        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("UAE"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("IDE0"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("IDE1"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("IDE2"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("IDE3"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI0"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI1"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI2"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI3"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI4"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI5"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI6"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSRAM"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SC IDE"));
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, 0, 0);
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("IDE"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("SCSI (Auto)"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A590/A2091 SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A590/A2091 #2 SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A4091 SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A4091 #2 SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A3000 SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("A4000T SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("CDTV SCSI"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("PCMCIA SRAM"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)_T("PCMCIA IDE"));
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, ctype, 0);
+
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_RESETCONTENT, 0, 0);
+       if (ctype >= HD_CONTROLLER_TYPE_IDE_FIRST && ctype <= HD_CONTROLLER_TYPE_SCSI_LAST) {
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("0"));
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("1"));
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("2"));
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("3"));
+               if (ctype >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctype <= HD_CONTROLLER_TYPE_SCSI_LAST) {
+                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("4"));
+                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("5"));
+                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("6"));
+               }
+               ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE);
+       } else {
+               ew(hDlg, IDC_HDF_CONTROLLER_UNIT, FALSE);
+       }
 }
 
 static void inithardfile (HWND hDlg)
@@ -9936,15 +10039,19 @@ static void inithardfile (HWND hDlg)
 
        ew (hDlg, IDC_HF_DOSTYPE, FALSE);
        ew (hDlg, IDC_HF_CREATE, FALSE);
-       inithdcontroller (hDlg);
+       inithdcontroller (hDlg, current_hfdlg.ci.controller_type);
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_RESETCONTENT, 0, 0);
        WIN32GUI_LoadUIString (IDS_HF_FS_CUSTOM, tmp, sizeof (tmp) / sizeof (TCHAR));
-       SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("OFS/FFS/RDB"));
+       SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("RDB/OFS/FFS"));
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("PFS3"));
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("PDS3"));
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SFS"));
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)tmp);
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_SETCURSEL, 0, 0);
+       setautocomplete (hDlg, IDC_PATH_NAME);
+       setautocomplete (hDlg, IDC_PATH_FILESYS);
+       addhistorymenu(hDlg, current_hfdlg.ci.rootdir, IDC_PATH_NAME, HISTORY_HDF, false);
+       addhistorymenu(hDlg, current_hfdlg.ci.filesys, IDC_PATH_FILESYS, HISTORY_FS, false);
 }
 
 static void sethfdostype (HWND hDlg, int idx)
@@ -10003,7 +10110,7 @@ static void updatehdfinfo (HWND hDlg, bool force, bool defaults)
                }
                if (defaults) {
                        if (hfd.flags & HFD_FLAGS_REALDRIVE) {
-                               if (current_hfdlg.ci.controller >= HD_CONTROLLER_IDE0 && current_hfdlg.ci.controller <= HD_CONTROLLER_IDE3) {
+                               if (current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST) {
                                        getchspgeometry (bsize, &current_hfdlg.ci.pcyls, &current_hfdlg.ci.pheads, &current_hfdlg.ci.psecs, true);
                                        if (current_hfdlg.forcedcylinders == 0)
                                                current_hfdlg.forcedcylinders = current_hfdlg.ci.pcyls;
@@ -10064,10 +10171,13 @@ static void updatehdfinfo (HWND hDlg, bool force, bool defaults)
        }
 }
 
-static void hardfileselecthdf (HWND hDlg, TCHAR *newpath)
+static void hardfileselecthdf (HWND hDlg, TCHAR *newpath, bool ask)
 {
-       DiskSelection (hDlg, IDC_PATH_NAME, 2, &workprefs, newpath);
-       GetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.ci.rootdir, sizeof current_hfdlg.ci.rootdir / sizeof (TCHAR));
+       if (ask) {
+               DiskSelection (hDlg, IDC_PATH_NAME, 2, &workprefs, newpath);
+               GetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.ci.rootdir, sizeof current_hfdlg.ci.rootdir / sizeof (TCHAR));
+               DISK_history_add(current_hfdlg.ci.rootdir, -1, HISTORY_HDF, 1);
+       }
        fullpath (current_hfdlg.ci.rootdir, sizeof current_hfdlg.ci.rootdir / sizeof (TCHAR));
        inithardfile (hDlg);
        hardfile_testrdb (&current_hfdlg);
@@ -10105,11 +10215,12 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
 
        case WM_INITDIALOG:
                recursive++;
-               inithdcontroller (hDlg);
-               if (current_tapedlg.ci.controller < HD_CONTROLLER_IDE0)
-                       current_tapedlg.ci.controller = (workprefs.a2091 || workprefs.a4091 || workprefs.cs_cdtvscsi || workprefs.cs_mbdmac >= 1) ? HD_CONTROLLER_SCSI0 : HD_CONTROLLER_IDE0;
-               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_tapedlg.ci.controller, 0);
-               SetDlgItemText (hDlg, IDC_PATH_NAME, current_tapedlg.ci.rootdir);
+               if (current_tapedlg.ci.controller_type < HD_CONTROLLER_TYPE_SCSI_AUTO)
+                       current_tapedlg.ci.controller_type = HD_CONTROLLER_TYPE_SCSI_AUTO;
+               inithdcontroller (hDlg, current_tapedlg.ci.controller_type);
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
+               setautocomplete (hDlg, IDC_PATH_NAME);
+               addhistorymenu(hDlg, current_tapedlg.ci.rootdir, IDC_PATH_NAME, HISTORY_TAPE, false);
                readonly = my_existsfile (current_tapedlg.ci.rootdir);
                CheckDlgButton (hDlg, IDC_TAPE_RW, current_tapedlg.ci.readonly == 0 && !readonly);
                ew (hDlg, IDC_TAPE_RW, !readonly);
@@ -10126,6 +10237,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                case IDC_TAPE_SELECT_FILE:
                        DiskSelection (hDlg, IDC_PATH_NAME, 18, &workprefs, NULL);
                        GetDlgItemText (hDlg, IDC_PATH_NAME, current_tapedlg.ci.rootdir, sizeof current_tapedlg.ci.rootdir / sizeof (TCHAR));
+                       DISK_history_add(current_tapedlg.ci.rootdir, -1, HISTORY_TAPE, 1);
                        fullpath (current_tapedlg.ci.rootdir, sizeof current_tapedlg.ci.rootdir / sizeof (TCHAR));
                        readonly = my_existsfile (current_tapedlg.ci.rootdir);
                        ew (hDlg, IDC_TAPE_RW, !readonly);
@@ -10146,6 +10258,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
                        }
                        _tcscpy (current_tapedlg.ci.rootdir, directory_path);
+                       DISK_history_add(current_tapedlg.ci.rootdir, -1, HISTORY_TAPE, 1);
                        readonly = my_existsfile (current_tapedlg.ci.rootdir);
                        ew (hDlg, IDC_TAPE_RW, !readonly);
                        if (readonly)
@@ -10160,8 +10273,16 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        break;
                case IDC_HDF_CONTROLLER:
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
+                       if (posn != CB_ERR) {
+                               current_tapedlg.ci.controller_type = posn;
+                               inithdcontroller (hDlg, current_tapedlg.ci.controller_type);
+                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
+                       }
+                       break;
+               case IDC_HDF_CONTROLLER_UNIT:
+                       posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
                        if (posn != CB_ERR)
-                               current_tapedlg.ci.controller = posn;
+                               current_tapedlg.ci.controller_unit = posn;
                        break;
                }
                current_tapedlg.ci.readonly = !ischecked (hDlg, IDC_TAPE_RW);
@@ -10180,10 +10301,10 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
 
        case WM_INITDIALOG:
                recursive++;
-               inithdcontroller (hDlg);
-               if (current_cddlg.ci.controller < HD_CONTROLLER_IDE0)
-                       current_cddlg.ci.controller = (workprefs.a2091 || workprefs.a4091 || workprefs.cs_cdtvscsi || workprefs.cs_mbdmac >= 1) ? HD_CONTROLLER_SCSI0 : HD_CONTROLLER_IDE0;
-               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_cddlg.ci.controller, 0);
+               if (current_cddlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE)
+                       current_cddlg.ci.controller_type = (workprefs.a2091 || workprefs.a4091 || workprefs.cs_cdtvscsi || (workprefs.cs_mbdmac & 3)) ? HD_CONTROLLER_TYPE_SCSI_AUTO : HD_CONTROLLER_TYPE_IDE_AUTO;
+               inithdcontroller (hDlg, current_cddlg.ci.controller_type);
+               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
                InitializeListView (hDlg);
                recursive--;
                customDlgType = IDD_CDDRIVE;
@@ -10210,8 +10331,16 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                        break;
                case IDC_HDF_CONTROLLER:
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
+                       if (posn != CB_ERR) {
+                               current_cddlg.ci.controller_type = posn;
+                               inithdcontroller (hDlg, current_cddlg.ci.controller_type);
+                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
+                       }
+                       break;
+               case IDC_HDF_CONTROLLER_UNIT:
+                       posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
                        if (posn != CB_ERR)
-                               current_cddlg.ci.controller = posn;
+                               current_cddlg.ci.controller_unit = posn;
                        break;
                }
                recursive--;
@@ -10225,7 +10354,7 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
        static int recursive = 0;
        LRESULT res, posn;
        TCHAR tmp[MAX_DPATH], fs[MAX_DPATH], dev[MAX_DPATH];
-       int hdctrlr;
+       int hdctrlr, hdunit;
        int v;
 
        switch (msg) {
@@ -10252,7 +10381,7 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                                TCHAR path[MAX_DPATH];
                                _tcscpy (path, s);
                                xfree (s);
-                               hardfileselecthdf (hDlg, path);
+                               hardfileselecthdf (hDlg, path, true);
                        }
                } else if (GetDlgCtrlID ((HWND)wParam) == IDC_FILESYS_SELECTOR) {
                        TCHAR *s = favoritepopup (hDlg);
@@ -10278,6 +10407,31 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                        break;
                recursive++;
 
+               if (HIWORD (wParam) == CBN_SELCHANGE || HIWORD (wParam) == CBN_KILLFOCUS)  {
+                       switch (LOWORD (wParam)) {
+                       case IDC_PATH_NAME:
+                               GetDlgItemText (hDlg, IDC_PATH_NAME, tmp, sizeof tmp / sizeof (TCHAR));
+                               if (_tcscmp (tmp, current_hfdlg.ci.rootdir)) {
+                                       _tcscpy (current_hfdlg.ci.rootdir, tmp);
+                                       hardfileselecthdf (hDlg, NULL, false);
+                               }
+                               break;
+                       case IDC_HDF_CONTROLLER:
+                               posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
+                               if (posn != CB_ERR) {
+                                       current_hfdlg.ci.controller_type = posn;
+                                       sethardfile (hDlg);
+                               }
+                               break;
+                       case IDC_HDF_CONTROLLER_UNIT:
+                               posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
+                               if (posn != CB_ERR) {
+                                       current_hfdlg.ci.controller_unit = posn;
+                                       sethardfile (hDlg);
+                               }
+                               break;
+                       }
+               }
                switch (LOWORD (wParam)) {
                case IDC_HF_SIZE:
                        ew (hDlg, IDC_HF_CREATE, CalculateHardfileSize (hDlg) > 0);
@@ -10299,19 +10453,22 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                                _tcscpy (dev, current_hfdlg.ci.devname);
                                bool rw = current_hfdlg.ci.readonly;
                                int bootpri = current_hfdlg.ci.bootpri;
-                               hdctrlr = current_hfdlg.ci.controller;
+                               hdctrlr = current_hfdlg.ci.controller_type;
+                               hdunit = current_hfdlg.ci.controller_unit;
                                default_hfdlg (&current_hfdlg, false);
                                _tcscpy (current_hfdlg.ci.filesys, fs);
                                _tcscpy (current_hfdlg.ci.devname, dev);
-                               current_hfdlg.ci.controller = hdctrlr;
+                               current_hfdlg.ci.controller_type = hdctrlr;
+                               current_hfdlg.ci.controller_unit = hdunit;
                                current_hfdlg.ci.bootpri = bootpri;
                                current_hfdlg.ci.readonly = rw;
-                               hardfileselecthdf (hDlg, NULL);
+                               hardfileselecthdf (hDlg, NULL, true);
                        }
                        break;
                case IDC_FILESYS_SELECTOR:
                        DiskSelection (hDlg, IDC_PATH_FILESYS, 12, &workprefs, 0);
                        GetDlgItemText (hDlg, IDC_PATH_FILESYS, current_hfdlg.ci.filesys, sizeof current_hfdlg.ci.filesys / sizeof (TCHAR));
+                       DISK_history_add(current_hfdlg.ci.filesys, -1, HISTORY_FS, 1);
                        break;
                case IDOK:
                        EndDialog (hDlg, 1);
@@ -10394,20 +10551,6 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                case IDC_HARDFILE_DEVICE:
                        GetDlgItemText (hDlg, IDC_HARDFILE_DEVICE, current_hfdlg.ci.devname, sizeof current_hfdlg.ci.devname / sizeof (TCHAR));
                        break;
-               case IDC_HDF_CONTROLLER:
-                       posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
-                       if (posn != CB_ERR) {
-                               current_hfdlg.ci.controller = posn;
-                               sethardfile (hDlg);
-                       }
-                       break;
-               case IDC_PATH_NAME:
-                       GetDlgItemText (hDlg, IDC_PATH_NAME, tmp, sizeof tmp / sizeof (TCHAR));
-                       if (_tcscmp (tmp, current_hfdlg.ci.rootdir)) {
-                               _tcscpy (current_hfdlg.ci.rootdir, tmp);
-                               updatehdfinfo (hDlg, true, false);
-                       }
-                       break;
                }
                recursive--;
 
@@ -10431,13 +10574,12 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        oposn = -1;
                        hdf_init_target ();
                        recursive++;
-                       inithdcontroller (hDlg);
+                       inithdcontroller (hDlg, current_hfdlg.ci.controller_type);
                        CheckDlgButton (hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly);
                        SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_RESETCONTENT, 0, 0);
                        ew (hDlg, IDC_HARDDRIVE_IMAGE, FALSE);
                        ew (hDlg, IDOK, FALSE);
                        ew (hDlg, IDC_HDF_RW, FALSE);
-                       ew (hDlg, IDC_HDF_CONTROLLER, FALSE);
                        index = -1;
                        for (i = 0; i < hdf_getnumharddrives (); i++) {
                                SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_ADDSTRING, 0, (LPARAM)hdf_getnameharddrive (i, 1, NULL, NULL));
@@ -10449,7 +10591,8 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        }
                        if (index >= 0) {
                                SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_SETCURSEL, index, 0);
-                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller, 0);
+                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller_type, 0);
+                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
                        }
                        recursive--;
                        return TRUE;
@@ -10500,23 +10643,32 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                        current_hfdlg.forcedcylinders = 0;
                                        current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0;
                                        ew (hDlg, IDC_HDF_CONTROLLER, ena);
+                                       ew (hDlg, IDC_HDF_CONTROLLER_UNIT, ena);
                                        SetDlgItemText (hDlg, IDC_HDFINFO, _T(""));
                                        SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                        updatehdfinfo (hDlg, true, true);
-                                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller, 0);
+                                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.ci.controller_type, 0);
+                                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
                                        CheckDlgButton(hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly);
                                        _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive ((int)posn, 4, &current_hfdlg.ci.blocksize, NULL));
                                }
                        }
                } else if (LOWORD (wParam) == IDC_HDF_CONTROLLER) {
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
-                       if (posn != CB_ERR) {
-                               current_hfdlg.ci.controller = posn;
+                       if (posn != CB_ERR && current_hfdlg.ci.controller_type != posn) {
+                               current_hfdlg.ci.controller_type = posn;
                                current_hfdlg.forcedcylinders = 0;
                                current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0;
                                SetDlgItemText (hDlg, IDC_HDFINFO, _T(""));
                                SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                updatehdfinfo (hDlg, true, true);
+                               inithdcontroller (hDlg, current_hfdlg.ci.controller_type);
+                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
+                       }
+               } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_UNIT) {
+                       posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0);
+                       if (posn != CB_ERR) {
+                               current_hfdlg.ci.controller_unit = posn;
                        }
                }
                recursive--;
@@ -10543,7 +10695,8 @@ static void new_cddrive (HWND hDlg, int entry)
 {
        struct uaedev_config_info ci = { 0 };
        ci.device_emu_unit = 0;
-       ci.controller = current_cddlg.ci.controller;
+       ci.controller_type = current_cddlg.ci.controller_type;
+       ci.controller_unit = current_cddlg.ci.controller_unit;
        ci.type = UAEDEV_CD;
        ci.readonly = true;
        ci.blocksize = 2048;
@@ -10554,7 +10707,8 @@ static void new_tapedrive (HWND hDlg, int entry)
 {
        struct uaedev_config_data *uci;
        struct uaedev_config_info ci = { 0 };
-       ci.controller = current_tapedlg.ci.controller;
+       ci.controller_type = current_tapedlg.ci.controller_type;
+       ci.controller_unit = current_tapedlg.ci.controller_unit;
        ci.readonly = current_tapedlg.ci.readonly;
        _tcscpy (ci.rootdir, current_tapedlg.ci.rootdir);
        ci.type = UAEDEV_TAPE;
@@ -10844,7 +10998,7 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                CheckDlgButton (hDlg, IDC_MAPDRIVES_LIMIT, workprefs.filesys_limit != 0);
                InitializeListView (hDlg);
                setautocomplete (hDlg, IDC_CD_TEXT);
-               addfloppyhistory_2 (hDlg, 0, IDC_CD_TEXT, HISTORY_CD);
+               addhistorymenu (hDlg, workprefs.cdslots[0].name, IDC_CD_TEXT, HISTORY_CD, true);
                addcdtype (hDlg, IDC_CD_TYPE);
                hilitehd (hDlg);
                break;
@@ -10877,7 +11031,7 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                        if (full_property_sheet)
                                workprefs.cdslots[0].type = SCSI_UNIT_DEFAULT;
                        addcdtype (hDlg, IDC_CD_TYPE);
-                       addfloppyhistory_2 (hDlg, 0, IDC_CD_TEXT, HISTORY_CD);
+                       addhistorymenu (hDlg, workprefs.cdslots[0].name, IDC_CD_TEXT, HISTORY_CD, true);
                        InitializeListView (hDlg);
                        hilitehd (hDlg);
                        break;
@@ -10907,7 +11061,7 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                                        }
                                }
                                addcdtype (hDlg, IDC_CD_TYPE);
-                               addfloppyhistory_2 (hDlg, 0, IDC_CD_TEXT, HISTORY_CD);
+                               addhistorymenu (hDlg, workprefs.cdslots[0].name, IDC_CD_TEXT, HISTORY_CD, true);
                                InitializeListView (hDlg);
                                hilitehd (hDlg);
                        }
@@ -11002,23 +11156,17 @@ static void floppytooltip (HWND hDlg, int num, uae_u32 crc32)
        SendMessage (ToolTipHWND, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
 }
 
-static void addfloppyhistory_2 (HWND hDlg, int n, int f_text, int type)
+static void addhistorymenu(HWND hDlg, const TCHAR *text, int f_text, int type, bool manglepath)
 {
        int i, j;
-       TCHAR *s, *text;
+       TCHAR *s;
        UAEREG *fkey;
-       int nn, curidx;
+       int nn = 1;
+       int curidx;
 
        if (f_text < 0)
                return;
        SendDlgItemMessage (hDlg, f_text, CB_RESETCONTENT, 0, 0);
-       if (type == HISTORY_CD) {
-               nn = 1;
-               text = workprefs.cdslots[0].name;
-       } else {
-               nn = workprefs.floppyslots[n].dfxtype + 1;
-               text = workprefs.floppyslots[n].df;
-       }
        SendDlgItemMessage (hDlg, f_text, WM_SETTEXT, 0, (LPARAM)text);
        fkey = read_disk_history (type);
        if (fkey == NULL)
@@ -11026,37 +11174,40 @@ static void addfloppyhistory_2 (HWND hDlg, int n, int f_text, int type)
        curidx = -1;
        i = 0;
        while (s = DISK_history_get (i, type)) {
-               TCHAR tmpname[MAX_DPATH], tmppath[MAX_DPATH], *p, *p2;
+               TCHAR tmpname[MAX_DPATH];
                if (_tcslen (s) == 0)
                        break;
                i++;
-               _tcscpy (tmppath, s);
-               p = tmppath + _tcslen (tmppath) - 1;
-               for (j = 0; uae_archive_extensions[j]; j++) {
-                       p2 = _tcsstr (tmppath, uae_archive_extensions[j]);
-                       if (p2) {
-                               p = p2;
-                               break;
+               if (manglepath) {
+                       TCHAR tmppath[MAX_DPATH], *p, *p2;
+                       _tcscpy (tmppath, s);
+                       p = tmppath + _tcslen (tmppath) - 1;
+                       for (j = 0; uae_archive_extensions[j]; j++) {
+                               p2 = _tcsstr (tmppath, uae_archive_extensions[j]);
+                               if (p2) {
+                                       p = p2;
+                                       break;
+                               }
                        }
-               }
-               while (p > tmppath) {
-                       if (*p == '\\' || *p == '/')
-                               break;
-                       p--;
-               }
-               _tcscpy (tmpname, p + 1);
-               *++p = 0;
-               if (tmppath[0]) {
-                       _tcscat (tmpname, _T(" { "));
-                       _tcscat (tmpname, tmppath);
-                       _tcscat (tmpname, _T(" }"));
+                       while (p > tmppath) {
+                               if (*p == '\\' || *p == '/')
+                                       break;
+                               p--;
+                       }
+                       _tcscpy (tmpname, p + 1);
+                       *++p = 0;
+                       if (tmppath[0]) {
+                               _tcscat (tmpname, _T(" { "));
+                               _tcscat (tmpname, tmppath);
+                               _tcscat (tmpname, _T(" }"));
+                       }
+               } else {
+                       _tcscpy (tmpname, s);
                }
                if (f_text >= 0)
                        SendDlgItemMessage (hDlg, f_text, CB_ADDSTRING, 0, (LPARAM)tmpname);
                if (!_tcscmp (text, s))
                        curidx = i - 1;
-               if (nn <= 0)
-                       break;
        }
        if (f_text >= 0 && curidx >= 0)
                SendDlgItemMessage (hDlg, f_text, CB_SETCURSEL, curidx, 0);
@@ -11083,7 +11234,7 @@ static void addfloppyhistory (HWND hDlg)
                else
                        f_text = IDC_DISKTEXT;
                if (f_text >= 0)
-                       addfloppyhistory_2 (hDlg, n, f_text, iscd (n) ? HISTORY_CD : HISTORY_FLOPPY);
+                       addhistorymenu (hDlg, workprefs.floppyslots[n].df, f_text, iscd (n) ? HISTORY_CD : HISTORY_FLOPPY, true);
        }
 }
 
index dab9f9fe10ef50d702cbcee54d200ed439b4e7ec..25f7e0cb77a0bb0bb11a08b84078a54cf1af6135 100644 (file)
@@ -18,6 +18,69 @@ Things that may happen in 2015:
 
 - restore only single input target to default.
 
+Beta 1:
+
+- Debugger TR command didn't handle linked resident lists correctly (inverted mask..).
+- TO debugger command also lists FileSysStartupMsg and DosEnvec of mounted devices.
+- Slow down 68EC020 RTE instruction, fast clock rate multiplier modes could have executed MOVE to
+  INTREQ + RTE combination too quickly (before Paula had cleared the interrupt) causing interrupt to
+  re-trigger immediately after RTE.
+- Added SCSI controller selection to GUI and config file. ("SCSI (Auto)" does same as old plain
+  SCSI selection = use first enabled SCSI controller).
+- More than 1 SCSI controller can be now active simultaneously. (For example A4000T + A4091)
+- Added support for two A590/A2091 and two A4091 boards, both (or even all 4) can be active at the same time.
+- Secondary A590/A2091 and A4091 share primary board's boot ROM by default. a2091_2_rom_file and
+  a4091_2_rom_file config file entry can be used to select other ROM version.
+- 280b7 sprite update missed AGA bordersprite condition, causing clipped sprites in some situations
+  (Silicon Graphics 2 / WFMH)
+- Rewritten directory filesystem Examine Next logic, now returned fib_DiskKey always have file/directory
+  entry specific unique value. Some programs check fib_DiskKey and (incorrectly) assume that it is unique
+  value and may also assume file must be same if both file's have same fib_DiskKey. Now also C:List KEY output
+  looks "correct". This needs testing because original (Tripos?) directory enumeration packet design is
+  not that good..
+- AGA border sprite bit set and if same scanline had at least 1 sprite that was outside of playfield and at
+  least 1 bitplane was active and BPLCON4 palette XOR value was non-zero: wrong background color was visible
+  in some situations. (Nexus 7 / Andromeda "shade cluster" part)
+- Some BEAMCON0 programmed mode emulation updates. VBSTRT/VBSTOP register values only affect screen if
+  VARVBEN bit is set.
+- Use also value stored in VBSTRT (vertical blank start) register when setting up programmed mode vertical
+  size, some weird modes can have (much) smaller VBSTRT than VSSTRT (vertical sync start). (Jtxrules by Illusion)
+- HBSTRT/HBSTOP register values are only used if BPLCON3 EXTBLKEN bit is set. (Demos Contactro and Jtxrules by Illusion)
+- BEAMCON0 HARDDIS bit also disables DDFSTRT hardware limit. (Weird stuff, VARBEAMEN disables it too,
+  even superhires mode disables it..)
+- Fixed "CPU trace blahblah" error after 68020+ state file was loaded and loaded program used bitfield instructions
+  later.
+- Split ROM images didn't load (again..) correctly if relative path mode was active.
+- Added support for missing Z2 RAM board sizes (64k/128k/256k/512k). Note that small boards (256k and less) can
+  be mapped at IO autoconfig base (0xe90000+) which makes predicting final address difficult: JIT (if enabled)
+  can't use direct mode to access this RAM board.
+- Added support for second Z2 fast RAM board. Size must be smaller or same as first board. (Makes JIT
+  board address calculation simpler)
+- Above two changes mean it is now possible to have total 6M of Z2 RAM in 24 bit addressing config with 2M gfx
+  board config (4M + 2M and 2M gfx) or less useful 8M fast + extra 256k of fast config...
+- Z2 gfx board JIT direct calculation didn't correctly align the board base address if Z2 RAM size was less than
+  Z2 gfx board size.
+- Implemented no-hack Z3 memory mapping, lets OS handle Z3 autoconfig without patching base addressess from
+  >=0x40000000 to >=0x10000000. This mode is not JIT Direct compatible. Option in Memory panel. Do not enable
+  unless you know what are you doing and you really need 100% matching real hardware Z3 address mapping.
+- Use no-hack Z3 allocation automatically if all configured boards fit in official Z3 space, fully JIT Direct
+  compatible. Requires 64-bit Windows and available space will be about 300M to 500M. RAM panel text string
+  shows free space. 32-bit Chip RAM does not count, it is not Z3 board and it is always located at 0x10000000.
+- Added 384M and 768M 32-bit Chip RAM size options. (768M fits perfectly at 0x10000000-0x3fffffff)
+- Added Z3 autoconfig advanced chipset option. If ticked (or A3000/A3000T/A4000/A4000T chipset extra selected),
+  Z33 boards will now appear at Z3 autoconfig space (0xFF000000), previously Z2 space was always used.
+  Z2 space is supported by AOS but most real, but not all, Z3 boards use Z3 space. Optional because not all
+  KS ROMs (for example A1200) support Z3 autoconfig space but do support Z3 boards.
+- Try to keep number of cylinders under 65536 when generating default geometry even if partition hardfile
+  is very large (>100G) for better old AOS compatibility. (Helps my big partition PFS3 testing..)
+- Hardware (Cirrus Logic) RTG board emulation incorrectly required UAE boot ROM.
+- 68030 MMU update from Previous, fixes some supervisor/write protect edge cases.
+- Added "history" menu to filesystem, hardfile and tape path selection text boxes.
+- Added portable mode (.ini) on/off state to Paths panel. Read-only, enabling it on the fly would cause
+  all kinds of side-effects. Unsupported warning removed.
+
+2.8.1
+
 Beta 8:
 
 - Tweaked 68020 reading from non-existing memory behavior.
index 162af4ebfc3c11530d7eb67233a2a1b7aaebbd9d..59724161a4bdb068d99a06ba2cc41f8ee8f7e877 100644 (file)
@@ -2218,11 +2218,12 @@ static const MemoryRegionOps lsi_io_ops = {
 };
 #endif
 
-void lsi_scsi_reset(DeviceState *dev)
+void lsi_scsi_reset(DeviceState *dev, void *privdata)
 {
     LSIState *s = LSI53C895A(dev);
 
     lsi_soft_reset(s);
+       s->bus.privdata = privdata;
 }
 
 void lsi_scsi_init(DeviceState *dev)
index 52757a59d3dcef3b3c3328a45c88cf5b95076156..d689072a96b112fa65a92e0d22707ca4108ffc8e 100644 (file)
@@ -299,7 +299,7 @@ typedef unsigned long dma_addr_t;
 
 void pci_set_irq(PCIDevice *pci_dev, int level);
 void lsi_scsi_init(DeviceState *dev);
-void lsi_scsi_reset(DeviceState *dev);
+void lsi_scsi_reset(DeviceState *dev, void*);
 
 static inline int32_t sextract32(uint32_t value, int start, int length)
 {
index 1ba56a0e3638faa50a8acea8ee503cac246930c4..04c8cda228540352b2b4ff35bf3bec8def88a62d 100644 (file)
@@ -130,6 +130,7 @@ struct SCSIBus {
 
     SCSISense unit_attention;
     const SCSIBusInfo *info;
+       void *privdata;
 };
 
 //void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
index 2182d5c2fbefdf322b5b4cdf61ea3ce75b2af614..77e45bc54280b86cf79e139fc97b754256b351f3 100644 (file)
@@ -15,6 +15,7 @@
 #include "memory.h"
 #include "zfile.h"
 #include "crc32.h"
+#include "fsdb.h"
 
 #include "autoconf.h"
 
@@ -86,7 +87,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
                        if (!_tcscmp(path + 1, rd->configname))
                                return rd;
                }
-               if (!_tcscmp(rl[i].path, path))
+               if (my_issamepath(rl[i].path, path))
                        return rl[i].rd;
        }
        return NULL;
@@ -1236,7 +1237,7 @@ struct zfile *read_rom_name (const TCHAR *filename)
        struct zfile *f;
 
        for (i = 0; i < romlist_cnt; i++) {
-               if (!_tcsicmp (filename, rl[i].path)) {
+               if (my_issamepath(filename, rl[i].path)) {
                        struct romdata *rd = rl[i].rd;
                        f = read_rom (rd);
                        if (f)
index e4933bfac9b028092806c5c39d30bd464e549ecd..ede12d61fb49c09a1046fd917da93e09ed294b09 100644 (file)
@@ -63,6 +63,8 @@
 #include "filesys.h"
 #include "inputrecord.h"
 #include "disk.h"
+#include "threaddep/thread.h"
+#include "a2091.h"
 
 int savestate_state = 0;
 static int savestate_first_capture;
@@ -552,7 +554,10 @@ void restore_state (const TCHAR *filename)
                        continue;
 #ifdef AUTOCONFIG
                } else if (!_tcscmp (name, _T("FRAM"))) {
-                       restore_fram (totallen, filepos);
+                       restore_fram (totallen, filepos, 0);
+                       continue;
+               } else if (!_tcscmp (name, _T("FRA2"))) {
+                       restore_fram (totallen, filepos, 1);
                        continue;
                } else if (!_tcscmp (name, _T("ZRAM"))) {
                        restore_zram (totallen, filepos, z3num++);
@@ -680,9 +685,17 @@ void restore_state (const TCHAR *filename)
                        end = restore_cdtv_dmac (chunk);
 #endif
                else if (!_tcscmp (name, _T("DMC2")))
-                       end = restore_scsi_dmac (chunk);
-               else if (!_tcscmp (name, _T("SCSI")))
-                       end = restore_scsi_device (chunk);
+                       end = restore_scsi_dmac (WDTYPE_A3000, chunk);
+               else if (!_tcscmp (name, _T("DMC3")))
+                       end = restore_scsi_dmac (WDTYPE_A2091, chunk);
+               else if (!_tcscmp (name, _T("DMC3")))
+                       end = restore_scsi_dmac (WDTYPE_A2091_2, chunk);
+               else if (!_tcscmp (name, _T("SCS2")))
+                       end = restore_scsi_device (WDTYPE_A3000, chunk);
+               else if (!_tcscmp (name, _T("SCS3")))
+                       end = restore_scsi_device (WDTYPE_A2091, chunk);
+               else if (!_tcscmp (name, _T("SCS4")))
+                       end = restore_scsi_device (WDTYPE_A2091_2, chunk);
                else if (!_tcscmp (name, _T("SCSD")))
                        end = restore_scsidev (chunk);
                else if (!_tcscmp (name, _T("GAYL")))
@@ -788,8 +801,10 @@ static void save_rams (struct zfile *f, int comp)
        dst = save_a3000hram (&len);
        save_chunk (f, dst, len, _T("A3K2"), comp);
 #ifdef AUTOCONFIG
-       dst = save_fram (&len);
+       dst = save_fram (&len, 0);
        save_chunk (f, dst, len, _T("FRAM"), comp);
+       dst = save_fram (&len, 1);
+       save_chunk (f, dst, len, _T("FRA2"), comp);
        dst = save_zram (&len, 0);
        save_chunk (f, dst, len, _T("ZRAM"), comp);
        dst = save_zram (&len, 1);
@@ -969,13 +984,23 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
        save_chunk (f, dst, len, _T("DMAC"), 0);
        xfree (dst);
 #endif
-       dst = save_scsi_dmac (&len, NULL);
+       dst = save_scsi_dmac (WDTYPE_A3000, &len, NULL);
        save_chunk (f, dst, len, _T("DMC2"), 0);
        xfree (dst);
        for (i = 0; i < 8; i++) {
-               dst = save_scsi_device (i, &len, NULL);
-               save_chunk (f, dst, len, _T("SCSI"), 0);
+               dst = save_scsi_device (WDTYPE_A3000, i, &len, NULL);
+               save_chunk (f, dst, len, _T("SCS2"), 0);
+               xfree (dst);
+       }
+       for (int ii = 0; ii < 2; ii++) {
+               dst = save_scsi_dmac (ii == 0 ? WDTYPE_A2091 : WDTYPE_A2091_2, &len, NULL);
+               save_chunk (f, dst, len, ii == 0 ? _T("DMC3") : _T("DMC4"), 0);
                xfree (dst);
+               for (i = 0; i < 8; i++) {
+                       dst = save_scsi_device (ii == 0 ? WDTYPE_A2091 : WDTYPE_A2091_2, i, &len, NULL);
+                       save_chunk (f, dst, len, ii == 0 ? _T("SCS3") : _T("SCS4"), 0);
+                       xfree (dst);
+               }
        }
        for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                dst = save_scsidev (i, &len, NULL);
@@ -1274,7 +1299,7 @@ void savestate_rewind (void)
        p += len;
 #ifdef AUTOCONFIG
        len = restore_u32_func (&p);
-       memcpy (save_fram (&dummy), p, currprefs.fastmem_size > len ? len : currprefs.fastmem_size);
+       memcpy (save_fram (&dummy, 0), p, currprefs.fastmem_size > len ? len : currprefs.fastmem_size);
        p += len;
        len = restore_u32_func (&p);
        memcpy (save_zram (&dummy, 0), p, currprefs.z3fastmem_size > len ? len : currprefs.z3fastmem_size);
@@ -1297,7 +1322,9 @@ void savestate_rewind (void)
                p = restore_cdtv_dmac (p);
 #endif
        if (restore_u32_func (&p))
-               p = restore_scsi_dmac (p);
+               p = restore_scsi_dmac (WDTYPE_A2091, p);
+       if (restore_u32_func (&p))
+               p = restore_scsi_dmac (WDTYPE_A3000, p);
        if (restore_u32_func (&p))
                p = restore_gayle (p);
        for (i = 0; i < 4; i++) {
@@ -1569,7 +1596,7 @@ retry2:
        tlen += len + 4;
        p += len;
 #ifdef AUTOCONFIG
-       dst = save_fram (&len);
+       dst = save_fram (&len, 0);
        if (bufcheck (st, p, len))
                goto retry;
        save_u32_func (&p, len);
@@ -1645,7 +1672,17 @@ retry2:
        p3 = p;
        save_u32_func (&p, 0);
        tlen += 4;
-       if (save_scsi_dmac (&len, p)) {
+       if (save_scsi_dmac (WDTYPE_A2091, &len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_scsi_dmac (WDTYPE_A3000, &len, p)) {
                save_u32_func (&p3, 1);
                tlen += len;
                p += len;
index 45211e29681baa559392b6beb72933ff3a2fb339..de05e2d17700ad33375c07da2db54489f8501926 100644 (file)
@@ -16,6 +16,7 @@
 #include "blkdev.h"
 #include "zfile.h"
 #include "memory.h"
+#include "threaddep/thread.h"
 #include "a2091.h"
 #include "fsdb.h"
 
index 3230da747e519ddbb8d3ad8074c40e84cefdbe7a..ac52058fb452f124a72ddf632545bfa0f6a113b0 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -304,7 +304,7 @@ int zfile_gettype (struct zfile *z)
                return ZFILE_DISKIMAGE;
        if (!memcmp (buf, "UAE-1ADF", 8))
                return ZFILE_DISKIMAGE;
-       if (!memcmp (buf, "Formatte", 89))
+       if (!memcmp (buf, "Formatte", 8))
                return ZFILE_DISKIMAGE;
        if (!memcmp (buf, "RDSK", 4))
                return ZFILE_HDFRDB;