]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2710b5
authorToni Wilen <twilen@winuae.net>
Sun, 2 Feb 2014 15:57:49 +0000 (17:57 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 2 Feb 2014 15:57:49 +0000 (17:57 +0200)
37 files changed:
cia.cpp
custom.cpp
disk.cpp
drawing.cpp
events.cpp
expansion.cpp
filesys.asm
filesys.cpp
filesys_bootrom.cpp
gencpu.cpp
genlinetoscr.cpp
gfxboard.cpp
include/a2091.h
include/blkdev.h
include/custom.h
include/events.h
include/filesys.h
include/memory.h
include/options.h
include/scsi.h
include/uaenative.h [new file with mode: 0644]
include/uni_common.h [new file with mode: 0644]
main.cpp
memory.cpp
od-win32/dinput.cpp
od-win32/hardfile_win32.cpp
od-win32/sysconfig.h
od-win32/win32.cpp
od-win32/win32.h
od-win32/winuae_msvc11/winuae_msvc.sln
od-win32/winuae_msvc11/winuae_msvc.vcxproj
od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters
od-win32/winuaechangelog.txt
od-win32/writelog.cpp
qemuvga/qemumemory.h
uaenative.cpp [new file with mode: 0644]
zfile.cpp

diff --git a/cia.cpp b/cia.cpp
index 3be2da65d455850a3047a37d226afa8e7ee81dbf..948b55bfd7ced5def5b5d5cbcd43f8c7e231f353 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -76,7 +76,7 @@ static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
 
 static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
 static int ciaatlatch, ciabtlatch;
-static bool oldled, oldovl, oldcd32mute;
+static bool oldovl, oldcd32mute;
 static bool led;
 static int led_old_brightness;
 static unsigned long led_cycles_on, led_cycles_off, led_cycle;
@@ -853,7 +853,7 @@ void CIAA_tod_inc (int cycles)
        event2_newevent_xx (-1, cycles + TOD_INC_DELAY, 0, CIAA_tod_handler);
 }
 
-static void bfe001_change (void)
+static void check_led (void)
 {
        uae_u8 v = ciaapra;
        bool led2;
@@ -865,6 +865,12 @@ static void bfe001_change (void)
                led = led2;
                led_old_brightness = -1;
        }
+}
+
+static void bfe001_change (void)
+{
+       uae_u8 v = ciaapra;
+       check_led ();
        if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
                oldovl = v & 1;
                if (!oldovl) {
@@ -1119,6 +1125,10 @@ static uae_u8 ReadCIAB (unsigned int addr)
        case 12:
                return ciabsdr;
        case 13:
+#if CIAB_DEBUG_IRQ
+               if (ciabicr & (0x80 | 0x40))
+                       write_log (_T("CIAB IRQ cleared\n"));
+#endif
                tmp = ciabicr & ~0x40;
                ciabicr = 0;
                return tmp;
@@ -1482,7 +1492,6 @@ void CIA_reset (void)
        kblostsynccnt = 0;
        serbits = 0;
        oldcd32mute = 1;
-       oldled = true;
        resetwarning_phase = resetwarning_timer = 0;
        heartbeat_cnt = 0;
        ciab_tod_event_state = 0;
@@ -1506,6 +1515,7 @@ void CIA_reset (void)
                DISK_select_set (ciabprb);
        }
        map_overlay (0);
+       check_led ();
 #ifdef SERIAL_PORT
        if (currprefs.use_serial && !savestate_state)
                serial_dtr_off (); /* Drop DTR at reset */
index ffe097f0d107306da144e70a9d6086c17605e83c..b964025c506d23c5bf2b848a04cc3cd0382cb69c 100644 (file)
@@ -64,7 +64,7 @@
 
 #define CUSTOM_DEBUG 0
 #define SPRITE_DEBUG 0
-#define SPRITE_DEBUG_MINY 0x0
+#define SPRITE_DEBUG_MINY 246
 #define SPRITE_DEBUG_MAXY 0x300
 #define SPR0_HPOS 0x15
 #define MAX_SPRITES 8
@@ -389,7 +389,6 @@ static uae_u32 thisline_changed;
 
 static struct decision thisline_decision;
 static int fetch_cycle, fetch_modulo_cycle;
-static int bitplane_dma_turned_on;
 
 enum plfstate
 {
@@ -399,10 +398,17 @@ enum plfstate
        plf_wait_stop,
        plf_passed_stop,
        plf_passed_stop2,
-       plf_end,
-       plf_finished
+       plf_end
 } plf_state;
 
+enum plfrenderstate
+{
+       plfr_idle,
+       plfr_active,
+       plfr_end,
+       plfr_finished
+} plfr_state;
+
 enum fetchstate {
        fetch_not_started,
        fetch_started_first,
@@ -492,6 +498,7 @@ void alloc_cycle_blitter (int hpos, uaecptr *ptr, int chnum)
                if (warned > 0) {
                        write_log (_T("buggy copper cycle conflict with blitter ch %c %08x <- %08x PC=%08x\n"), 'A' + (chnum - 1), *ptr, srcptr, m68k_getpc ());
                        warned--;
+                       //activate_debugger ();
                }
                if ((currprefs.cs_hacks & 1) && currprefs.cpu_model == 68000)
                        *ptr = srcptr;
@@ -918,9 +925,10 @@ static uae_u64 fetched_aga[MAX_PLANES];
 
 /* Expansions from bplcon0/bplcon1.  */
 static int toscr_res, toscr_res2p;
-static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, fetchwidth;
+static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, toscr_nr_planes_shifter;
+static int fetchwidth;
 static int toscr_delay[2], toscr_delay_adjusted[2];
-static int delay_cycles, delay_lastcycle;
+static int delay_cycles, delay_lastcycle[2];
 static bool bplcon1_written;
 
 /* The number of bits left from the last fetched words.
@@ -1009,6 +1017,17 @@ STATIC_INLINE int is_bitplane_dma_inline (int hpos)
        return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
 }
 
+static int islinetoggle (void)
+{
+       int linetoggle = 0;
+       if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
+               linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
+       } else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) {
+               linetoggle = 1; // hardwired NTSC Agnus
+       }
+       return linetoggle;
+}
+
 /* Expand bplcon0/bplcon1 into the toscr_xxx variables.  */
 static void compute_toscr_delay (int bplcon1)
 {
@@ -1035,6 +1054,14 @@ static void compute_toscr_delay (int bplcon1)
 #endif
 }
 
+static void set_delay_lastcycle (void)
+{
+       delay_lastcycle[0] = ((maxhpos + 1) * 2 + 0) << bplcon0_res;
+       delay_lastcycle[1] = delay_lastcycle[0];
+       if (islinetoggle ())
+               delay_lastcycle[1]++;
+}
+
 static int bpldmasetuphpos, bpldmasetuphpos_diff;
 static int bpldmasetupphase;
 static void update_toscr_planes (int fm);
@@ -1069,7 +1096,7 @@ static void setup_fmodes (int hpos)
        fetchmode_size = 16 << fetchmode;
        fetchmode_bytes = 2 << fetchmode;
        fetchmode_mask = fetchmode_size - 1;
-       delay_lastcycle = (maxhpos * 2) << bplcon0_res;
+       set_delay_lastcycle ();
        compute_toscr_delay (bplcon1);
 
        if (thisline_decision.plfleft < 0) {
@@ -1343,7 +1370,7 @@ STATIC_INLINE void do_delays_3_ecs (int nbits)
                        
 
                        if (todisplay_fetched[oddeven] && dp == delay) {
-                               for (int i = oddeven; i < MAX_PLANES; i += 2) {
+                               for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
                                        todisplay2[i] = todisplay[i];
                                }
                                todisplay_fetched[oddeven] = false;
@@ -1359,7 +1386,7 @@ STATIC_INLINE void do_delays_3_ecs (int nbits)
                        do_tosrc (oddeven, 2, diff, 0);
                        nbits2 -= diff;
                        if (todisplay_fetched[oddeven]) {
-                               for (int i = oddeven; i < MAX_PLANES; i += 2)
+                               for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2)
                                        todisplay2[i] = todisplay[i];
                                todisplay_fetched[oddeven] = false;
                        }
@@ -1382,7 +1409,8 @@ STATIC_INLINE void do_delays_fast_3_ecs (int nbits)
                do_tosrc (0, 1, diff, 0);
                nbits2 -= diff;
                if (todisplay_fetched[0]) {
-                       memcpy (todisplay2, todisplay, sizeof todisplay);
+                       for (int i = 0; i < toscr_nr_planes_shifter; i++)
+                               todisplay2[i] = todisplay[i];
                        todisplay_fetched[0] = false;
                        todisplay_fetched[1] = false;
                }
@@ -1404,7 +1432,7 @@ STATIC_INLINE void do_delays_3_aga (int nbits, int fm)
                        do_tosrc (oddeven, 2, diff, fm);
                        nbits2 -= diff;
                        if (todisplay_fetched[oddeven]) {
-                               for (int i = oddeven; i < MAX_PLANES; i += 2)
+                               for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2)
                                        todisplay2_aga[i] = todisplay_aga[i];
                                todisplay_fetched[oddeven] = false;
                        }
@@ -1426,7 +1454,8 @@ STATIC_INLINE void do_delays_fast_3_aga (int nbits, int fm)
                do_tosrc (0, 1, diff, fm);
                nbits2 -= diff;
                if (todisplay_fetched[0]) {
-                       memcpy (todisplay2_aga, todisplay_aga, sizeof todisplay_aga);
+                       for (int i = 0; i < toscr_nr_planes_shifter; i++)
+                               todisplay2_aga[i] = todisplay_aga[i];
                        todisplay_fetched[0] = false;
                        todisplay_fetched[1] = false;
                }
@@ -1483,29 +1512,41 @@ STATIC_INLINE void do_delays_fast (int nbits, int fm)
        }
 }
 
+static void toscr_right_edge (int nbits, int fm)
+{
+       // Emulate hpos counter (delay_cycles) reseting at the end of scanline.
+       // (Result is ugly shift in graphics in far right overscan)
+       int diff = delay_lastcycle[lol] - delay_cycles;
+       int nbits2 = nbits;
+       if (nbits2 >= diff) {
+               do_delays (diff, fm);
+               nbits2 -= diff;
+               delay_cycles = 0;
+               toscr_delay[0] -= 2;
+               toscr_delay[0] &= fetchmode_mask;
+               toscr_delay[1] -= 2;
+               toscr_delay[1] &= fetchmode_mask;
+       }
+       if (nbits2) {
+               do_delays (nbits2, fm);
+               delay_cycles += nbits2;
+       }
+}
+
 STATIC_INLINE void toscr_1 (int nbits, int fm)
 {
-       if (delay_cycles + nbits >= delay_lastcycle) {
-               // Emulate hpos counter (delay_cycles) reseting at the end of scanline.
-               // It can cause glitch in far right overscan.
-               int diff = delay_lastcycle - delay_cycles;
-               int nbits2 = nbits;
-               if (nbits2 >= diff) {
-                       do_delays (diff, fm);
-                       nbits2 -= diff;
-                       delay_cycles = 0;
-               }
-               if (nbits2)
-                       do_delays (nbits2, fm);
+       if (delay_cycles + nbits >= delay_lastcycle[lol]) {
+               toscr_right_edge (nbits, fm);
        } else if (toscr_delay[0] == toscr_delay[1]) {
                // Most common case.
                do_delays_fast (nbits, fm);
+               delay_cycles += nbits;
        } else {
                do_delays (nbits, fm);
+               delay_cycles += nbits;
        }
 
        out_nbits += nbits;
-       delay_cycles += nbits;
        if (out_nbits == 32) {
                int i;
                uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4;
@@ -1571,26 +1612,21 @@ static int flush_plane_data (int fm)
                i += 32 - out_nbits;
                toscr_1 (32 - out_nbits, fm);
        }
-       i += 32;
-
-       memset (todisplay, 0, sizeof todisplay);
-       if (fm)
-               memset (todisplay_aga, 0, sizeof todisplay_aga);
 
+       i += 32;
        toscr_1 (16, fm);
        toscr_1 (16, fm);
 
        if (fm == 2) {
-               /* flush AGA full 64-bit shift register */
+               /* flush AGA full 64-bit shift register + possible data in todisplay */
+               i += 32;
+               toscr_1 (16, fm);
+               toscr_1 (16, fm);
                i += 32;
                toscr_1 (16, fm);
                toscr_1 (16, fm);
        }
 
-       memset (todisplay2, 0, sizeof todisplay2);
-       if (fm)
-               memset (todisplay2_aga, 0, sizeof todisplay2_aga);
-
        return i >> (1 + toscr_res);
 }
 
@@ -1601,6 +1637,28 @@ STATIC_INLINE void flush_display (int fm)
        toscr_nbits = 0;
 }
 
+static void update_denise_shifter_planes (int hpos)
+{
+       int np = GET_PLANES (bplcon0d);
+       // if DMA has ended but there is still data waiting in todisplay,
+       // it must be flushed out before number of planes change
+       if (np < toscr_nr_planes_shifter && hpos > thisline_decision.plfright && thisline_decision.plfright && (todisplay_fetched[0] || todisplay_fetched[1])) {
+               int diff = (hpos - thisline_decision.plfright) << (1 + toscr_res);
+               while (diff >= 16) {
+                       toscr_1 (16, fetchmode);
+                       diff -= 16;
+               }
+               if (diff)
+                       toscr_1 (diff, fetchmode);
+               thisline_decision.plfright += hpos - thisline_decision.plfright;
+       }
+       toscr_nr_planes_shifter = np;
+       if (isocs7planes ()) {
+               if (toscr_nr_planes_shifter < 6)
+                       toscr_nr_planes_shifter = 6;
+       }
+}
+
 STATIC_INLINE void update_denise (int hpos)
 {
        int res = GET_RES_DENISE (bplcon0d);
@@ -1620,6 +1678,7 @@ STATIC_INLINE void update_denise (int hpos)
        } else {
                toscr_nr_planes2 = toscr_nr_planes;
        }
+       toscr_nr_planes_shifter = toscr_nr_planes2;
 }
 
 STATIC_INLINE void fetch_start (int hpos)
@@ -1953,23 +2012,28 @@ static void do_long_fetch (int hpos, int nwords, int dma, int fm)
 
 #endif
 
-static void finish_last_fetch (int pos, int fm)
+static void finish_last_fetch (int pos, int fm, bool reallylast)
 {
        if (thisline_decision.plfleft < 0)
                return;
-       if (plf_state >= plf_end)
+//     if (reallylast)
+//             plf_state = plf_end;
+       if (plfr_state >= plfr_end)
                return;
-       plf_state = plf_end;
+       plfr_state = plfr_end;
 
        flush_display (fm);
-       // This may not be the last fetch, store current endpos for future use.
-       // There is at least one demo that has two DDFSTRT-DDFSTOP horizontal sections.
-       thisline_decision.plfright = pos;
-
-       if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
-               ddfstate = DIW_waiting_start;
-               fetch_state = fetch_not_started;
+       if (!reallylast) {
+               // This may not be the last fetch, store current endpos for future use.
+               // There is at least one demo that has two DDFSTRT-DDFSTOP horizontal sections.
+               thisline_decision.plfright = pos;
+#if 1
+               if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
+                       ddfstate = DIW_waiting_start;
+                       fetch_state = fetch_not_started;
+               }
        }
+#endif
 }
 /* check special case where last fetch wraps to next line
  * this makes totally corrupted and flickering display on
@@ -1981,7 +2045,7 @@ static void maybe_finish_last_fetch (int pos, int fm)
        bool done = false;
 
        if (plf_state != plf_passed_stop2 || (fetch_state != fetch_started && fetch_state != fetch_started_first) || !dmaen (DMA_BITPLANE)) {
-               finish_last_fetch (pos, fm);
+               finish_last_fetch (pos, fm, true);
                return;
        }
        do {
@@ -2018,7 +2082,7 @@ static void maybe_finish_last_fetch (int pos, int fm)
                        default:
                        goto end;
                        }
-                       break;
+                       break;  
                }
                fetch_cycle++;
                toscr_nbits += toscr_res2p;
@@ -2037,19 +2101,16 @@ static void maybe_finish_last_fetch (int pos, int fm)
        }
 
 end:
-       finish_last_fetch (pos, fm);
+       finish_last_fetch (pos, fm, true);
 }
 
 
 /* make sure fetch that goes beyond maxhpos is finished */
 static void finish_final_fetch (void)
 {
-       if (plf_state < plf_end) {
-               finish_last_fetch (maxhpos, fetchmode);
-               if (plf_state != plf_end)
-                       return;
-       }
-       plf_state = plf_finished;
+       if (plfr_state < plf_end)
+               finish_last_fetch (maxhpos, fetchmode, true);
+       plfr_state = plfr_finished;
        // This is really the end of scanline, we can finally flush all remaining data.
        thisline_decision.plfright += flush_plane_data (fetchmode);
        thisline_decision.plflinelen = out_offs;
@@ -2059,18 +2120,20 @@ static void finish_final_fetch (void)
 
 STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int fm)
 {
-       if (plf_state < plf_passed_stop && pos == ddfstop_to_test)
-               plf_state = plf_passed_stop;
+       if (dma || (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
+               if (plf_state < plf_passed_stop && pos == ddfstop_to_test)
+                       plf_state = plf_passed_stop;
 
-       if ((fetch_cycle & fetchunit_mask) == 0) {
-               if (plf_state == plf_passed_stop2) {
-                       finish_last_fetch (pos, fm);
-                       return 1;
-               }
-               if (plf_state == plf_passed_stop) {
-                       plf_state = plf_passed_stop2;
-               } else if (plf_state == plf_passed_stop2) {
-                       plf_state = plf_end;
+               if ((fetch_cycle & fetchunit_mask) == 0) {
+                       if (plf_state == plf_passed_stop2) {
+                               finish_last_fetch (pos, fm, false);
+                               return 1;
+                       }
+                       if (plf_state == plf_passed_stop) {
+                               plf_state = plf_passed_stop2;
+                       } else if (plf_state == plf_passed_stop2) {
+                               plf_state = plf_end;
+                       }
                }
        }
 
@@ -2187,6 +2250,17 @@ static void update_fetch_x (int until, int fm)
        flush_display (fm);
 }
 
+STATIC_INLINE int get_ddfstop_to_test (int hpos)
+{
+       /* We need an explicit test against HARD_DDF_STOP here to guard against
+       programs that move the DDFSTOP before our current position before we
+       reach it.  */
+       int ddfstop_to_test = HARD_DDF_STOP;
+       if (ddfstop >= hpos && plfstop < ddfstop_to_test)
+               ddfstop_to_test = plfstop;
+       return ddfstop_to_test;
+
+}
 STATIC_INLINE void update_fetch (int until, int fm)
 {
        int pos;
@@ -2197,13 +2271,7 @@ STATIC_INLINE void update_fetch (int until, int fm)
        if (nodraw () || plf_state >= plf_end)
                return;
 
-       /* We need an explicit test against HARD_DDF_STOP here to guard against
-       programs that move the DDFSTOP before our current position before we
-       reach it.  */
-       ddfstop_to_test = HARD_DDF_STOP;
-       if (ddfstop >= last_fetch_hpos && plfstop < ddfstop_to_test)
-               ddfstop_to_test = plfstop;
-
+       ddfstop_to_test = get_ddfstop_to_test (last_fetch_hpos);
        pos = last_fetch_hpos;
        cycle_diagram_shift = last_fetch_hpos - fetch_cycle;
 
@@ -2239,7 +2307,7 @@ STATIC_INLINE void update_fetch (int until, int fm)
        }
 
        // vdiw getting cleared mid-scan = fetches also stop
-       if (diwstate == DIW_waiting_start && plf_state < plf_wait_stop) {
+       if ((diwstate == DIW_waiting_start || !dma) && plf_state < plf_wait_stop) {
                // ecs = continue at passed_stop
                // ocs = line is done
                if (currprefs.chipset_mask & CSMASK_ECS_AGNUS)
@@ -2379,11 +2447,18 @@ static void start_bpl_dma (int hpos, int hstart)
 #else
        fetch_state = fetch_started;
 #endif
+       plfr_state = plfr_active;
        ddfstate = DIW_waiting_stop;
+       if (hstart >= get_ddfstop_to_test (hpos))
+               plf_state = plf_passed_stop;
 
        if (!bpldmawasactive) {
 
-               plfstrt_sprite = plfstrt;
+               plfstrt_sprite = hstart;
+               // OCS Agnus needs at least 1 empty cycle between
+               // sprite fetch and bitplane cycle sequence start.
+               if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
+                       plfstrt_sprite--;
                fetch_cycle = 0;
                update_denise (last_fetch_hpos);
                if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) {
@@ -2415,6 +2490,8 @@ static void start_bpl_dma (int hpos, int hstart)
                update_fetch_x (hstart, fetchmode);
        }
 
+       estimate_last_fetch_cycle (hstart);
+
        last_fetch_hpos = hstart;
 
 
@@ -2432,6 +2509,7 @@ static void start_bpl_dma (int hpos, int hstart)
 #endif
 }
 
+#if 0
 /* this may turn on datafetch if program turns dma on during the ddf */
 static void maybe_start_bpl_dma (int hpos)
 {
@@ -2449,12 +2527,13 @@ static void maybe_start_bpl_dma (int hpos)
                return;
        if (hpos <= plfstrt)
                return;
-       if (hpos > plfstop - fetchunit)
+       if (hpos >= plfstop)
                return;
        if (ddfstate != DIW_waiting_start)
                plf_state = plf_passed_stop;
        start_bpl_dma (hpos, hpos);
 }
+#endif
 
 STATIC_INLINE bool cant_this_last_line (void)
 {
@@ -2484,34 +2563,58 @@ STATIC_INLINE void decide_line (int hpos)
                return;
 
        if (fetch_state == fetch_not_started) {
-               int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2;
-               if (last_decide_line_hpos < start && hpos >= start) {
-                       if (plf_state == plf_idle || plf_state == plf_end)
-                               plf_state = plf_start;
+               bool dma = dmaen (DMA_BITPLANE) != 0;
+               bool dmaecs = dma || (currprefs.chipset_mask & CSMASK_ECS_AGNUS);
+               int bplstart = hpos;
+
+               // dma needs to be on when matching ddfstrt if OCS Agnus
+               if (dmaecs) {
+                       int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2;
+                       if (last_decide_line_hpos < start && hpos >= start) {
+                               if (plf_state >= plf_passed_stop2 || plf_state == plf_idle) {
+                                       plf_state = plf_start;
+                               }
+                       }
                }
-               if ((diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) {
-                       int ok = 0;
-               
-                       if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
-                               if (plf_state == plf_start)
-                                       plf_state = plf_active;
-                               if (plf_state == plf_active)
-                                       ok = 1;
-                               /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored
-                               * (correct fix would be emulate this delay for every custom register, but why bother..) */
-                               if (hpos - 2 == ddfstrt_old_hpos)
-                                       ok = 0;
+
+               if (diwstate == DIW_waiting_stop) {
+
+                       if (dmaecs) {
+                               if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
+                                       /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored
+                                       * (correct fix would be emulate this delay for every custom register, but why bother..) */
+                                       if (plf_state == plf_start && hpos - 2 != ddfstrt_old_hpos)
+                                               plf_state = plf_active;
+                                       bplstart = plfstrt;
+                               }
                        }
-                       if (ok && diwstate == DIW_waiting_stop) {
-                               if (dmaen (DMA_BITPLANE) && bitplane_dma_turned_on + 4 < hpos) {
-                                       start_bpl_dma (hpos, plfstrt);
-                                       estimate_last_fetch_cycle (plfstrt);
+
+                       if (dmaecs) {
+                               // did we just match ddfstop but missed ddfstrt? DMA starts from passed plfstop state.
+                               if (last_decide_line_hpos > plfstrt && (plf_state == plf_active || plf_state == plf_wait_stop) && diwstate == DIW_waiting_stop) {
+                                       int stop = get_ddfstop_to_test (last_decide_line_hpos);
+                                       if (last_decide_line_hpos < stop && hpos >= stop) {
+                                               if (dma) {
+                                                       // we did, fetches start!
+                                                       bplstart = plfstop;
+                                                       plf_state = plf_active;
+                                               } else {
+                                                       // line done
+                                                       plf_state = plf_end;
+                                               }
+                                       }
                                }
-                               last_decide_line_hpos = hpos;
+                       }
+
+                       if (dma) {
+                               if (plf_state == plf_active && (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) || hpos >= 0x18)) {
+                                       start_bpl_dma (hpos, bplstart);
+                                       last_decide_line_hpos = hpos;
        #ifndef CUSTOM_SIMPLE
-                               do_sprites (hpos);
+                                       do_sprites (hpos);
        #endif
-                               return;
+                                       return;
+                               }
                        }
                }
        }
@@ -3299,12 +3402,12 @@ static void reset_decisions (void)
        reset_moddelays ();
        reset_bplldelays ();
        reset_dbplh_all (256);
-       bitplane_dma_turned_on = 0;
+       delay_cycles = 0;
+       compute_toscr_delay (bplcon1);
 
-       if (plf_state > plf_active)
-               plf_state = plf_idle;
-       if (plf_state == plf_active && !(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
+       if (plf_state >= plf_passed_stop2)
                plf_state = plf_idle;
+       plfr_state = plfr_idle;
 
        /* ECS/AGA and ddfstop > maxhpos == always-on display */
        if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
@@ -3315,7 +3418,16 @@ static void reset_decisions (void)
        }
 
        memset (outword, 0, sizeof outword);
+       memset (fetched, 0, sizeof fetched);
        todisplay_fetched[0] = todisplay_fetched[1] = false;
+       memset (todisplay, 0, sizeof todisplay);
+       memset (todisplay2, 0, sizeof todisplay2);
+#ifdef AGA
+       if (currprefs.chipset_mask & CSMASK_AGA) {
+               memset (todisplay_aga, 0, sizeof todisplay_aga);
+               memset (todisplay2_aga, 0, sizeof todisplay2_aga);
+       }
+#endif
 
        if (bitplane_line_crossing) {
                // BPL1DAT would have been written after end of last scanline.
@@ -3346,17 +3458,6 @@ static void reset_decisions (void)
 #endif
 }
 
-static int islinetoggle (void)
-{
-       int linetoggle = 0;
-       if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
-               linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
-       } else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) {
-               linetoggle = 1; // hardwired NTSC Agnus
-       }
-       return linetoggle;
-}
-
 int vsynctimebase_orig;
 
 void compute_vsynctime (void)
@@ -3726,7 +3827,7 @@ void init_hz (bool fullinit)
                vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);;
                minfirstline = vsstop > vbstop ? vsstop : vbstop;
                if (minfirstline > maxvpos / 2) 
-                       minfirstline = vsstop > vsstop ? vbstop : vsstop;
+                       minfirstline = vsstop > vbstop ? vbstop : vsstop;
                if (minfirstline < 2)
                        minfirstline = 2;
                if (minfirstline >= maxvpos)
@@ -3754,7 +3855,7 @@ void init_hz (bool fullinit)
        if (vblank_hz > 300)
                vblank_hz = 300;
        maxhpos_short = maxhpos;
-       delay_lastcycle = (maxhpos * 2) << bplcon0_res;
+       set_delay_lastcycle ();
        if (beamcon0 & 0x80) {
                if (hbstrt > maxhpos)
                        hsyncstartpos = hbstrt + 1;
@@ -3894,7 +3995,7 @@ static uae_u32 REGPARAM2 timehack_helper (TrapContext *context)
 /*
 * register functions
 */
-STATIC_INLINE uae_u16 DENISEID (int *missing)
+static uae_u16 DENISEID (int *missing)
 {
        *missing = 0;
        if (currprefs.cs_deniserev >= 0)
@@ -4013,6 +4114,14 @@ static uae_u16 VPOSR (void)
        return vp;
 }
 
+static void vposback (int oldvpos)
+{
+       if (cop_state.state == COP_wait && oldvpos == cop_state.vcmp) {
+               copper_enabled_thisline = 0;
+               unset_special (SPCFLAG_COPPER);
+       }
+}
+
 static void VPOSW (uae_u16 v)
 {
        int oldvpos = vpos;
@@ -4040,12 +4149,24 @@ static void VPOSW (uae_u16 v)
                vpos = oldvpos;
 }
 
+
 static void VHPOSW (uae_u16 v)
 {
        int oldvpos = vpos;
 #if 0
        if (M68K_GETPC < 0xf00000 || 1)
                write_log (_T("VHPOSW %04X PC=%08x\n"), v, M68K_GETPC);
+#endif
+#if 0
+       int hp = v & 0xff;
+       int oldhp = current_hpos ();
+       if (hp != oldhp) {
+               if (hp >= maxhpos)
+                       hp = maxhpos - 1;
+               eventtab[ev_hsync].oldcycles = get_cycles () - hp * CYCLE_UNIT;
+               eventtab[ev_hsync].evtime = eventtab[ev_hsync].oldcycles + HSYNCTIME;
+               events_schedule ();
+       }
 #endif
        v >>= 8; // lets ignore hpos for now
        vpos &= 0xff00;
@@ -4055,6 +4176,10 @@ static void VHPOSW (uae_u16 v)
        } else if (vpos < minfirstline && oldvpos < minfirstline) {
                vpos = oldvpos;
        }
+#if 0
+       if (vpos < oldvpos)
+               vposback (oldvpos);
+#endif
 }
 
 static uae_u16 VHPOSR (void)
@@ -4281,10 +4406,16 @@ static void DMACON (int hpos, uae_u16 v)
 
        if (changed & (DMA_MASTER | DMA_BITPLANE)) {
                ddf_change = vpos;
-               if (dmaen (DMA_BITPLANE))
-                       maybe_start_bpl_dma (hpos);
+#if 0
+               if (dmaen (DMA_BITPLANE)) {
+                       if (vpos == 0xba)
+                               write_log (_T("*"));
+//                     maybe_start_bpl_dma (hpos);
+               } else {
+                       write_log (_T("!"));
+               }
+#endif
        }
-
        events_schedule();
 }
 
@@ -4335,6 +4466,25 @@ STATIC_INLINE int use_eventmode (uae_u16 v)
        return 0;
 }
 
+static void rethink_intreq (void)
+{
+       serial_check_irq ();
+       rethink_cias ();
+#ifdef A2065
+       rethink_a2065 ();
+#endif
+#ifdef A2091
+       rethink_a2091 ();
+#endif
+#ifdef CDTV
+       rethink_cdtv ();
+#endif
+#ifdef CD32
+       rethink_akiko ();
+#endif
+       rethink_gayle ();
+}
+
 static void send_interrupt_do (uae_u32 v)
 {
        INTREQ_0 (0x8000 | (1 << v));
@@ -4353,15 +4503,24 @@ void send_interrupt (int num, int delay)
        }
 }
 
+static int int_recursive; // yes, bad idea.
+
 static void send_intena_do (uae_u32 v)
 {
-       intena_internal = v;
+       setclr (&intena_internal, v);
        doint ();
+       int_recursive++;
+       rethink_intreq ();
+       int_recursive--;
 }
+
 static void send_intreq_do (uae_u32 v)
 {
-       intreq_internal = v;
+       setclr (&intreq_internal, v);
        doint ();
+       int_recursive++;
+       rethink_intreq ();
+       int_recursive--;
 }
 
 static void INTENA (uae_u16 v)
@@ -4372,7 +4531,7 @@ static void INTENA (uae_u16 v)
        if (!(v & 0x8000) && old == intena)
                return;
        if (use_eventmode (v)) {
-               event2_newevent_xx (-1, INT_PROCESSING_DELAY, intena, send_intena_do);
+               event2_newevent_xx (-1, INT_PROCESSING_DELAY, v, send_intena_do);
        } else {
                intena_internal = intena;
                if (v & 0x8000)
@@ -4395,56 +4554,52 @@ void INTREQ_f (uae_u16 v)
 {
        if (use_eventmode (v)) {
                setclr (&intreq, v);
-               send_intreq_do (intreq);
+               send_intreq_do (v);
        } else {
                setclr (&intreq, v);
                setclr (&intreq_internal, v);
        }
 }
 
-void INTREQ_0 (uae_u16 v)
+bool INTREQ_0 (uae_u16 v)
 {
 #if 0
        if (!(v & 0x8000) && (v & (0x80 | 0x100 | 0x200 | 0x400) != 0x0780))
                write_log (_T("audirq clear %04x %04x\n"), v, intreq);
 #endif
-
        uae_u16 old = intreq;
        setclr (&intreq, v);
 
-       if (use_eventmode (v)) {
+       if (int_recursive) {
+               // don't add new event if this call came from send_intreq_do/rethink
+               // and intreq didn't change.
+               // it wouldn't make any difference except to slow down everything
+               if (old == intreq)
+                       return false;
+       }
+
+       if ((use_eventmode (v) || event2_count)) {
                // don't bother to waste time for interrupt queuing if nothing changes
-               // but only if we are sure there is no queued changes
+               // but only if we are sure there is no other queued changes
                if (old == intreq && intreq_internal == intreq)
-                       return;
-               event2_newevent_xx (-1, INT_PROCESSING_DELAY, intreq, send_intreq_do);
+                       return false;
+               event2_newevent_xx (-1, INT_PROCESSING_DELAY, v, send_intreq_do);
+               return false;
        } else {
+               uae_u16 old2 = intreq_internal;
                intreq_internal = intreq;
-               if (intreq == old)
-                       return;
-               if (v & 0x8000)
+               if (old == intreq && old2 == intreq_internal)
+                       return false;
+               if ((v & 0x8000) || currprefs.cpu_cycle_exact)
                        doint ();
+               return true;
        }
 }
 
 void INTREQ (uae_u16 data)
 {
-       INTREQ_0 (data);
-       serial_check_irq ();
-       rethink_cias ();
-#ifdef A2065
-       rethink_a2065 ();
-#endif
-#ifdef A2091
-       rethink_a2091 ();
-#endif
-#ifdef CDTV
-       rethink_cdtv ();
-#endif
-#ifdef CD32
-       rethink_akiko ();
-#endif
-       rethink_gayle ();
+       if (INTREQ_0 (data))
+               rethink_intreq ();
 }
 
 static void ADKCON (int hpos, uae_u16 v)
@@ -4601,6 +4756,8 @@ static void BPLCON0_Denise (int hpos, uae_u16 v, bool immediate)
 #endif
        if (thisline_decision.plfleft < 0)
                update_denise (hpos);
+       else
+               update_denise_shifter_planes (hpos);
 }
 
 static void BPLCON0 (int hpos, uae_u16 v)
@@ -4748,7 +4905,7 @@ static void BPLxDAT (int hpos, int num, uae_u16 v)
                bpl1dat_written = true;
                bpl1dat_written_at_least_once = true;
                if (thisline_decision.plfleft < 0) {
-                       thisline_decision.plfleft = hpos;
+                       thisline_decision.plfleft = (hpos + 3) & ~1;
                        reset_bpl_vars ();
                        update_denise (hpos);
                }
@@ -6925,6 +7082,7 @@ static void hsync_scandoubler (void)
 
        reset_decisions ();
        plf_state = plf_idle;
+       plfr_state = plfr_idle;
 
        // copy color changes
        dip1 = curr_drawinfo + next_lineno - 1;
index 33972653c41b27f653c63218304a4279b7cde4cf..f3ef066090cc81295cbe0ee761dd4918ffb22d37 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -932,13 +932,22 @@ static bool diskfile_iswriteprotect (struct uae_prefs *p, const TCHAR *fname, in
        return wrprot1;
 }
 
+static bool isrecognizedext (const TCHAR *name)
+{
+       const TCHAR *ext = _tcsrchr (name, '.');
+       if (ext) {
+               if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img"))) 
+                       return true;
+       }
+       return false;
+}
+
 static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake, bool forcedwriteprotect)
 {
        uae_u8 buffer[2 + 2 + 4 + 4];
        trackid *tid;
        int num_tracks, size;
        int canauto;
-       const TCHAR *ext;
 
        drive_image_free (drv);
        DISK_validate_filename (p, fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
@@ -954,13 +963,6 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
 
        gui_disk_image_change (dnum, fname, drv->wrprot);
 
-       canauto = 0;
-       ext = _tcsrchr (fname, '.');
-       if (ext) {
-               if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img"))) 
-                       canauto = 1;
-       }
-
        if (!drv->motoroff) {
                drv->dskready_up_time = DSKREADY_UP_TIME;
                drv->dskready_down_time = 0;
@@ -993,6 +995,12 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                zfile_fseek (drv->diskfile, 0, SEEK_SET);
        }
 
+       canauto = 0;
+       if (isrecognizedext (fname)) 
+               canauto = 1;
+       if (!canauto && drv->diskfile && isrecognizedext (zfile_getname (drv->diskfile)))
+               canauto = 1;
+
        if (drv->catweasel) {
 
                drv->wrprot = true;
index 56ba5c1d640a87191f681907b0ba3a163e9c7168..efe3a66377df1a24e786470bb997cae6130261d0 100644 (file)
@@ -743,9 +743,6 @@ static int playfield_start, playfield_end;
 static int real_playfield_start, real_playfield_end;
 static int linetoscr_diw_start, linetoscr_diw_end;
 static int native_ddf_left, native_ddf_right;
-#if 0
-static bool can_have_bordersprite;
-#endif
 
 static int pixels_offset;
 static int src_pixel, ham_src_pixel;
@@ -1567,13 +1564,49 @@ static void pfield_do_linetoscr (int start, int stop, bool blank)
 
 }
 
-// left or right border sprite
-static void pfield_do_linetoscr_border (int start, int stop, bool blank)
+// left or right AGA border sprite
+static void pfield_do_linetoscr_bordersprite_aga (int start, int stop, bool blank)
 {
-       bool old = issprites;
-       issprites = colors_for_drawing.bordersprite != 0;
-       pfield_do_linetoscr (start, stop, blank);
-       issprites = old;
+       if (res_shift == 0) {
+               switch (gfxvidinfo.drawbuffer.pixbytes) {
+               case 2: src_pixel = linetoscr_16_aga_spronly (LTPARMS); break;
+               case 4: src_pixel = linetoscr_32_aga_spronly (LTPARMS); break;
+               }
+       } else if (res_shift == 2) {
+               switch (gfxvidinfo.drawbuffer.pixbytes) {
+               case 2: src_pixel = linetoscr_16_stretch2_aga_spronly (LTPARMS); break;
+               case 4: src_pixel = linetoscr_32_stretch2_aga_spronly (LTPARMS); break;
+               }
+       } else if (res_shift == 1) {
+               switch (gfxvidinfo.drawbuffer.pixbytes) {
+               case 2: src_pixel = linetoscr_16_stretch1_aga_spronly (LTPARMS); break;
+               case 4: src_pixel = linetoscr_32_stretch1_aga_spronly (LTPARMS); break;
+               }
+       } else if (res_shift == -1) {
+               if (currprefs.gfx_lores_mode) {
+                       switch (gfxvidinfo.drawbuffer.pixbytes) {
+                       case 2: src_pixel = linetoscr_16_shrink1f_aga_spronly (LTPARMS); break;
+                       case 4: src_pixel = linetoscr_32_shrink1f_aga_spronly (LTPARMS); break;
+                       }
+               } else {
+                       switch (gfxvidinfo.drawbuffer.pixbytes) {
+                       case 2: src_pixel = linetoscr_16_shrink1_aga_spronly (LTPARMS); break;
+                       case 4: src_pixel = linetoscr_32_shrink1_aga_spronly (LTPARMS); break;
+                       }
+               }
+       } else if (res_shift == -2) {
+               if (currprefs.gfx_lores_mode) {
+                       switch (gfxvidinfo.drawbuffer.pixbytes) {
+                       case 2: src_pixel = linetoscr_16_shrink2f_aga_spronly (LTPARMS); break;
+                       case 4: src_pixel = linetoscr_32_shrink2f_aga_spronly (LTPARMS); break;
+                       }
+               } else {
+                       switch (gfxvidinfo.drawbuffer.pixbytes) {
+                       case 2: src_pixel = linetoscr_16_shrink2_aga_spronly (LTPARMS); break;
+                       case 4: src_pixel = linetoscr_32_shrink2_aga_spronly (LTPARMS); break;
+                       }
+               }
+       }
 }
 
 static void dummy_worker (int start, int stop, bool blank)
@@ -2411,7 +2444,12 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                        }
                }
 
-               do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno);
+#ifdef AGA
+               if (dip_for_drawing->nr_sprites && colors_for_drawing.bordersprite)
+                       do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr, lineno);
+               else
+#endif
+                       do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno);
 
                if (dh == dh_emerg)
                        memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth);
@@ -2462,21 +2500,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
 #ifdef AGA
                if (dosprites) {
 
-                       int i;
-
-                       for (i = 0; i < dip_for_drawing->nr_sprites; i++)
+                       for (int i = 0; i < dip_for_drawing->nr_sprites; i++)
                                draw_sprites_aga (curr_sprite_entries + dip_for_drawing->first_sprite_entry + i, 1);
-                       uae_u16 oxor = bplxor;
-                       if (dp_for_drawing->ham_seen) {
-                               int todraw_amiga = res_shift_from_window (visible_right_border - visible_left_border);
-                               init_ham_decoding ();
-                               memset (ham_linebuf + ham_decode_pixel, 0, todraw_amiga * sizeof (uae_u32));
-                       }
-                       if (dip_for_drawing->nr_color_changes) {
-                               bplxor = 0;
-                               do_color_changes (pfield_do_fill_line, pfield_do_linetoscr_border, lineno);
-                               bplxor = oxor;
-                       }
+                       do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_bordersprite_aga, lineno);
 #else
                if (0) {
 #endif
index 23e9a2e120149b2dae6c043690573d812fcc8715..4563424c096f3a968edc60ace6d7d0de32a1079d 100644 (file)
@@ -40,8 +40,6 @@ void events_schedule (void)
        nextevent = currcycle + mintime;
 }
 
-static int iwas1 = 123, iwas2 = 123, ihandled = 123;
-
 void do_cycles_slow (unsigned long cycles_to_add)
 {
        if ((pissoff -= cycles_to_add) >= 0)
@@ -83,12 +81,13 @@ void do_cycles_slow (unsigned long cycles_to_add)
                currcycle = nextevent;
 
                for (i = 0; i < ev_max; i++) {
-                       iwas1 = i;
                        if (eventtab[i].active && eventtab[i].evtime == currcycle) {
-                               iwas2 = i;
-                               ihandled = -1;
-                               (*eventtab[i].handler)();
-                               ihandled = 1;
+                               if (eventtab[i].handler == NULL) {
+                                       gui_message(_T("eventtab[%d].handler is null!\n"), i);
+                                       eventtab[i].active = 0;
+                               } else {
+                                       (*eventtab[i].handler)();
+                               }
                        }
                }
                events_schedule ();
index 5df8c53a18566b38ee760b48e43a300fefd5577e..a0634b751191555e6186da23c6112c2675954c73 100644 (file)
@@ -1238,7 +1238,7 @@ static void expamem_init_a2091 (void)
 static void expamem_init_a4091 (void)
 {
 #ifdef NCR
-       ncr_init ();
+       ncr_autoconfig_init ();
 #endif
 }
 static void expamem_init_gfxboard_memory (void)
index fc68435e937e97a401874757f48acf74bddece64..f16b63be15164a9c004ab6d768b95c8313cace43 100644 (file)
@@ -163,6 +163,25 @@ filesys_init:
 FSIN_explibok:
        move.l d0,a4
 
+       ; create fake configdev
+       exg a4,a6
+       jsr -$030(a6) ;expansion/AllocConfigDev
+       tst.l d0
+       beq.s .nocd
+       move.l d0,a0
+       lea start(pc),a1
+       move.l a1,d0
+       clr.w d0
+       move.l d0,32(a0)
+       move.l #65536,36(a0)
+       move.w #$0104,16(a0) ;type + product
+       move.w #2011,16+4(a0) ;manufacturer
+       moveq #1,d0
+       move.l d0,22(a0) ;serial
+       jsr -$01e(a6) ;expansion/AddConfigDev
+.nocd
+       exg a4,a6
+
        tst.l $10c(a5)
        beq.w FSIN_none
 
index 9af52a1bba44673a87b24c00407118eecdf038f9..b1ba2be035448169b920f7a3f55dc1ae00e87565 100644 (file)
@@ -45,6 +45,7 @@
 #include "gayle.h"
 #include "savestate.h"
 #include "a2091.h"
+#include "ncr_scsi.h"
 #include "cdtv.h"
 #include "sana2.h"
 #include "bsdsocket.h"
@@ -55,6 +56,7 @@
 #include "blkdev.h"
 #include "isofs_api.h"
 #include "scsi.h"
+#include "uaenative.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -828,15 +830,25 @@ static void initialize_mountinfo (void)
                        gayle_add_ide_unit (uci->controller - HD_CONTROLLER_IDE0, uci);
                        allocuci (&currprefs, nr, -1);
                } else if (uci->controller <= HD_CONTROLLER_SCSI6) {
-                       if (currprefs.cs_mbdmac > 0) {
+                       if (currprefs.cs_mbdmac == 1) {
 #ifdef A2091
                                a3000_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
                                allocuci (&currprefs, nr, -1);
+#endif
+                       } else if (currprefs.cs_mbdmac == 2) {
+#ifdef NCR
+                               a4000t_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);      
+                               allocuci (&currprefs, nr, -1);
 #endif
                        } else if (currprefs.cs_a2091) {
 #ifdef A2091
                                a2091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
                                allocuci (&currprefs, nr, -1);
+#endif
+                       } else if (currprefs.cs_a4091) {
+#ifdef NCR
+                               a4091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
+                               allocuci (&currprefs, nr, -1);
 #endif
                        } else if (currprefs.cs_cdtvscsi) {
 #ifdef CDTV
@@ -6289,6 +6301,9 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context)
 #ifdef BSDSOCKET
        resaddr = bsdlib_startup (resaddr);
 #endif
+#ifdef WITH_UAENATIVE
+       resaddr = uaenative_startup (resaddr);
+#endif
 #ifdef SCSIEMU
        resaddr = scsidev_startup (resaddr);
 #endif
index 0119d3fedc5f751f880a73170c310af27477eb30..50948e856f77af6fd09005ac03912ede5715d767 100644 (file)
@@ -1,13 +1,13 @@
  db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x60); db(0x02); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0xe8);
- db(0x00); db(0x00); db(0x08); db(0x84); db(0x00); db(0x00); db(0x00); db(0xe0);
- db(0x00); db(0x00); db(0x02); db(0x44); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x00); db(0x00); db(0x03); db(0x52); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x13); db(0x76); db(0x43); db(0xfa); db(0x18); db(0x81);
+ db(0x60); db(0x02); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0b); db(0x20);
+ db(0x00); db(0x00); db(0x08); db(0xbc); db(0x00); db(0x00); db(0x00); db(0xe0);
+ db(0x00); db(0x00); db(0x02); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x24);
+ db(0x00); db(0x00); db(0x03); db(0x8a); db(0x00); db(0x00); db(0x00); db(0x00);
+ db(0x00); db(0x00); db(0x13); db(0xae); db(0x43); db(0xfa); db(0x18); db(0xb9);
  db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
  db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0xe0); db(0xe2); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x11); db(0x61); db(0x00); db(0x17); db(0x6a); db(0x4e); db(0x90);
+ db(0x72); db(0x11); db(0x61); db(0x00); db(0x17); db(0xa2); db(0x4e); db(0x90);
  db(0x4a); db(0x80); db(0x67); db(0x4c); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x40);
  db(0x70); db(0x14); db(0x24); db(0x00); db(0x72); db(0x01); db(0x4e); db(0xae);
  db(0x20); db(0x68); db(0x00); db(0x02); db(0x2f); db(0x08); db(0x4e); db(0x90);
  db(0x20); db(0x5f); db(0x58); db(0x8f); db(0x48); db(0xe7); db(0xff); db(0x7e);
  db(0x22); db(0x4e); db(0x20); db(0x08); db(0x30); db(0x7c); db(0xff); db(0xb8);
- db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x12); db(0xb8);
- db(0x61); db(0x00); db(0x16); db(0x80); db(0x4c); db(0xdf); db(0x7e); db(0xff);
+ db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x12); db(0xf0);
+ db(0x61); db(0x00); db(0x16); db(0xb8); db(0x4c); db(0xdf); db(0x7e); db(0xff);
  db(0x4e); db(0x75); db(0x00); db(0x00); db(0x08); db(0x00); db(0x00); db(0x02);
  db(0x67); db(0x06); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0x00); db(0x00);
  db(0x4e); db(0xf9); db(0x00); db(0xf0); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00); db(0x16); db(0xc0);
- db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x17); db(0xe2); db(0x70); db(0x24);
+ db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00); db(0x16); db(0xf8);
+ db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x18); db(0x1a); db(0x70); db(0x24);
  db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
- db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x17); db(0xd2); db(0x70); db(0x00);
+ db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x18); db(0x0a); db(0x70); db(0x00);
  db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
+ db(0xc9); db(0x4e); db(0x4e); db(0xae); db(0xff); db(0xd0); db(0x4a); db(0x80);
+ db(0x67); db(0x2c); db(0x20); db(0x40); db(0x43); db(0xfa); db(0xfe); db(0xe2);
+ db(0x20); db(0x09); db(0x42); db(0x40); db(0x21); db(0x40); db(0x00); db(0x20);
+ db(0x21); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x00); db(0x00); db(0x24);
+ db(0x31); db(0x7c); db(0x01); db(0x04); db(0x00); db(0x10); db(0x31); db(0x7c);
+ db(0x07); db(0xdb); db(0x00); db(0x14); db(0x70); db(0x01); db(0x21); db(0x40);
+ db(0x00); db(0x16); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0xc9); db(0x4e);
  db(0x4a); db(0xad); db(0x01); db(0x0c); db(0x67); db(0x00); db(0x00); db(0x5c);
  db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x34); db(0x22); db(0x3c);
  db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
  db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x4c); db(0xdf);
  db(0x07); db(0x03); db(0x4e); db(0x75); db(0x52); db(0x91); db(0x70); db(0x00);
  db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00);
- db(0xfc); db(0xe0); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0xfc); db(0xa8); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01);
  db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40);
  db(0x41); db(0xfa); db(0x15); db(0x02); db(0x23); db(0x48); db(0x00); db(0x0a);
  db(0x41); db(0xfa); db(0xfe); db(0xd2); db(0x23); db(0x48); db(0x00); db(0x0e);
  db(0x30); db(0x3c); db(0xff); db(0x18); db(0x61); db(0x00); db(0x0e); db(0x58);
  db(0x4e); db(0x90); db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f);
  db(0x4a); db(0x80); db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00);
- db(0x17); db(0x70); db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf6); db(0x8e);
+ db(0x17); db(0x70); db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf6); db(0x56);
  db(0x20); db(0x08); db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20);
  db(0x70); db(0xff); db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07);
  db(0x00); db(0x00); db(0x67); db(0x40); db(0x0c); db(0x03); db(0x00); db(0x80);
  db(0x48); db(0xe7); db(0xc0); db(0x80); db(0x30); db(0x3c); db(0xff); db(0x38);
  db(0x72); db(0x66); db(0x61); db(0x00); db(0x00); db(0x0a); db(0x4e); db(0x90);
  db(0x4c); db(0xdf); db(0x01); db(0x03); db(0x4e); db(0x75); db(0x41); db(0xfa);
- db(0xe8); db(0x44); db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff);
+ db(0xe8); db(0x0c); db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff);
  db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x69); db(0x6e); db(0x70); db(0x75);
  db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
  db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72); db(0x2e); db(0x64);
index e262a64c3b28ac518ca38e5488b80874da3441c1..342dcdb69e77fd3fc56363c6455bf64dbb2b01f6 100644 (file)
@@ -508,6 +508,13 @@ static const char *gen_nextibyte (int flags)
        return buffer;
 }
 
+static void makefromsr (void)
+{
+       printf ("\tMakeFromSR();\n");
+       if (using_ce || using_ce020)
+               printf ("\tregs.ipl_pin = intlev ();\n");
+}
+
 static void check_ipl (void)
 {
        if (using_ce || using_ce020)
@@ -2794,7 +2801,7 @@ static void gen_opcode (unsigned long int opcode)
                        fill_prefetch_next ();
                }
                printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                break;
        case i_ANDSR:
                printf ("\tMakeSR ();\n");
@@ -2810,7 +2817,7 @@ static void gen_opcode (unsigned long int opcode)
                        fill_prefetch_next ();
                }
                printf ("\tregs.sr &= src;\n");
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                break;
        case i_SUB:
        {
@@ -3315,7 +3322,7 @@ static void gen_opcode (unsigned long int opcode)
                        addcycles000 (6);
                        printf ("\tregs.sr = src;\n");
                }
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                if (cpu_level <= 1) {
                        // 68000 does 2xprefetch
                        sync_m68k_pc ();
@@ -3415,7 +3422,7 @@ static void gen_opcode (unsigned long int opcode)
                        genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        printf ("\tregs.sr = src;\n");
                }
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                printf ("\tm68k_setstopped ();\n");
                sync_m68k_pc ();
                // STOP does not prefetch anything
@@ -3428,7 +3435,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tsr = %s (4);\n", srcwi);
                printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
                printf ("\tregs.sr = sr;\n");
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                printf ("\tm68k_setstopped();\n");
                m68k_pc_offset += 4;
                sync_m68k_pc ();
@@ -3441,7 +3448,7 @@ static void gen_opcode (unsigned long int opcode)
                        genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
                        printf ("\tregs.sr = sr;\n");
                        setpc ("pc");
-                       printf ("\tMakeFromSR ();\n");
+                       makefromsr ();
                } else if (cpu_level == 1 && using_prefetch) {
                    int old_brace_level = n_braces;
                        printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
@@ -3458,7 +3465,8 @@ static void gen_opcode (unsigned long int opcode)
                    printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
                    printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
                    pop_braces (old_brace_level);
-                   printf ("\tregs.sr = newsr; MakeFromSR ();\n");
+                   printf ("\tregs.sr = newsr;\n");
+                       makefromsr ();
                    printf ("\tif (newpc & 1) {\n");
                    printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
                        printf ("\t\tgoto %s;\n", endlabelstr);
@@ -3500,9 +3508,12 @@ static void gen_opcode (unsigned long int opcode)
                            printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
                        }
                    printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
-                   printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
+                   printf ("\t\tregs.sr = newsr;\n");
+                       makefromsr ();
+                       printf ("}\n");
                    pop_braces (old_brace_level);
-                   printf ("\tregs.sr = newsr; MakeFromSR ();\n");
+                   printf ("\tregs.sr = newsr;\n");
+                       makefromsr ();
                    printf ("\tif (newpc & 1) {\n");
                    printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
                        printf ("\t\tgoto %s;\n", endlabelstr);
@@ -3620,7 +3631,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                printf ("\tregs.sr |= sr;\n");
                setpc ("pc");
-               printf ("\tMakeFromSR ();\n");
+               makefromsr ();
                printf ("\tif (m68k_getpc () & 1) {\n");
                printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
                setpc ("oldpc");
@@ -3795,9 +3806,9 @@ static void gen_opcode (unsigned long int opcode)
                        curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA);
                //genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
                //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
-               fill_prefetch_next ();
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
+               fill_prefetch_next ();
                genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_PEA:
@@ -4532,6 +4543,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("else");
                        start_brace ();
                        printf ("\n");
+                       get_prefetch_020 ();
                        if (cpu_level >= 4) {
                                // apparently 68040/060 needs to always write at the end of RMW cycle
                                printf ("\t");
index ff08dc244f201acc32101b355a5dacaf48a7f54f..cad58008a273c6bf6c965d146f41f61252602617 100644 (file)
@@ -118,24 +118,30 @@ static void out_linetoscr_decl (DEPTH_T bpp, HMODE_T hmode, int aga, int spr)
 {
        outlnf ("static int NOINLINE linetoscr_%s%s%s%s (int spix, int dpix, int dpix_end)",
                get_depth_str (bpp),
-               get_hmode_str (hmode), aga ? "_aga" : "", spr ? "_spr" : "");
+               get_hmode_str (hmode), aga ? "_aga" : "", spr > 0 ? "_spr" : (spr < 0 ? "_spronly" : ""));
 }
 
 static void out_linetoscr_do_srcpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
 {
-       if (aga && cmode != CMODE_DUALPF) {
-               if (spr)
-                       outln (     "    sprpix_val = pixdata.apixels[spix];");
-               outln (         "    spix_val = pixdata.apixels[spix] ^ xor_val;");
-       } else if (cmode != CMODE_HAM) {
-               outln (         "    spix_val = pixdata.apixels[spix];");
-               if (spr)
-                       outln (     "    sprpix_val = spix_val;");
+       if (spr < 0) {
+               outln (     "    sprpix_val = 0;");
+       } else {
+               if (aga && cmode != CMODE_DUALPF) {
+                       if (spr)
+                               outln (     "    sprpix_val = pixdata.apixels[spix];");
+                       outln (         "    spix_val = pixdata.apixels[spix] ^ xor_val;");
+               } else if (cmode != CMODE_HAM) {
+                       outln (         "    spix_val = pixdata.apixels[spix];");
+                       if (spr)
+                               outln (     "    sprpix_val = spix_val;");
+               }
        }
 }
 
 static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
 {
+       if (spr < 0)
+               return;
        if (aga && cmode == CMODE_HAM) {
                outln (     "    spix_val = ham_linebuf[spix];");
                outln (     "    dpix_val = CONVERT_RGB (spix_val);");
@@ -171,6 +177,8 @@ static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_
 
 static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
 {
+       if (spr < 0)
+               return;
        if (hmode == HMODE_HALVE1F) {
                outln (         "    {");
                outln (         "    uae_u32 tmp_val;");
@@ -216,7 +224,7 @@ static void put_dpix (const char *var)
        outlnf ("    buf[dpix++] = %s;", var);
 }
 
-static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt)
+static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt, int spr)
 {
        if (aga) {
                if (cnt == 1) {
@@ -325,8 +333,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
        outln (         "while (dpix < dpix_end) {");
        if (spr)
                outln (         "    uae_u32 sprpix_val;");
-       outln (         "    uae_u32 spix_val;");
-       outln (         "    uae_u32 dpix_val;");
+       if (spr >= 0) {
+               outln (         "    uae_u32 spix_val;");
+               outln (         "    uae_u32 dpix_val;");
+       }
        outln (         "    uae_u32 out_val;");
        outln (         "");
 
@@ -334,7 +344,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
        out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr);
        out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr);
 
-       outln (         "    out_val = dpix_val;");
+       if (spr >= 0)
+               outln (         "    out_val = dpix_val;");
+       else
+               outln (         "    out_val = colors_for_drawing.acolors[0];");
 
        if (hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && bpp == DEPTH_16BPP && spr == 0) {
                out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr);
@@ -353,14 +366,14 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
                        outln ( "    dpix += 2;");
                } else if (bpp == DEPTH_16BPP) {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 2);
+                               out_sprite (bpp, hmode, cmode, aga, 2, spr);
                        } else {
                                outln ( "    *((uae_u32 *)&buf[dpix]) = out_val;");
                                outln ( "    dpix += 2;");
                        }
                } else {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 2);
+                               out_sprite (bpp, hmode, cmode, aga, 2, spr);
                        } else {
                                put_dpix ("out_val");
                                put_dpix ("out_val");
@@ -372,7 +385,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
                        outln ( "    dpix += 4;");
                } else if (bpp == DEPTH_16BPP) {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 4);
+                               out_sprite (bpp, hmode, cmode, aga, 4, spr);
                        } else {
                                outln ( "    *((uae_u32 *)&buf[dpix]) = out_val;");
                                outln ( "    dpix += 2;");
@@ -381,7 +394,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
                        }
                } else {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 4);
+                               out_sprite (bpp, hmode, cmode, aga, 4, spr);
                        } else {
                                put_dpix ("out_val");
                                put_dpix ("out_val");
@@ -392,14 +405,14 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
        } else {
                if (bpp == DEPTH_16BPP) {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 1);
+                               out_sprite (bpp, hmode, cmode, aga, 1, spr);
                        } else {
                                outln ( "    *((uae_u32 *)&buf[dpix]) = out_val;");
                                outln ( "    dpix += 2;");
                        }
                } else {
                        if (spr) {
-                               out_sprite (bpp, hmode, cmode, aga, 1);
+                               out_sprite (bpp, hmode, cmode, aga, 1, spr);
                        } else {
                                put_dpix ("out_val");
                        }
@@ -438,18 +451,23 @@ static void out_linetoscr (DEPTH_T bpp, HMODE_T hmode, int aga, int spr)
        outlnf (        "    %s *buf = (%s *) xlinebuffer;", get_depth_type_str (bpp), get_depth_type_str (bpp));
        if (spr)
                outln ( "    uae_u8 sprcol;");
-       if (aga)
+       if (aga && spr >= 0)
                outln ( "    uae_u8 xor_val = bplxor;");
        outln  (        "");
 
-       outln  (        "    if (bplham) {");
-       out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_HAM);
-       outln  (        "    } else if (bpldualpf) {");
-       out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_DUALPF);
-       outln  (        "    } else if (bplehb) {");
-       out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_EXTRAHB);
-       outln  (        "    } else {");
-       out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
+       if (spr >= 0) {
+               outln  (        "    if (bplham) {");
+               out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_HAM);
+               outln  (        "    } else if (bpldualpf) {");
+               out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_DUALPF);
+               outln  (        "    } else if (bplehb) {");
+               out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_EXTRAHB);
+               outln  (        "    } else {");
+               out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
+       } else {
+               outln  (        "    if (1) {");
+               out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
+       }
 
        outln  (        "    }\n");
        outln  (        "    return spix;");
@@ -479,7 +497,7 @@ int main (int argc, char *argv[])
        set_outfile (stdout);
 
        outln ("/*");
-       outln (" * E-UAE - The portable Amiga emulator.");
+       outln (" * UAE - The portable Amiga emulator.");
        outln (" *");
        outln (" * This file was generated by genlinetoscr. Don't edit.");
        outln (" */");
@@ -489,7 +507,9 @@ int main (int argc, char *argv[])
                for (aga = 0; aga <= 1 ; aga++) {
                        if (aga && bpp == DEPTH_8BPP)
                                continue;
-                       for (spr = 0; spr <= 1; spr++) {
+                       for (spr = -1; spr <= 1; spr++) {
+                               if (!aga && spr < 0)
+                                       continue;
                                for (hmode = HMODE_NORMAL; hmode <= HMODE_MAX; hmode++)
                                        out_linetoscr (bpp, hmode, aga, spr);
                        }
index 1c88e645bdf1e51798f6694cbb0e3126a59d37b5..b0a65a715c50ff686d861343e3d18750f977f24f 100644 (file)
@@ -11,9 +11,9 @@
 #define MEMLOGR 0
 #define MEMLOGW 0
 #define MEMLOGINDIRECT 0
-#define MEMDEBUG 0
+#define MEMDEBUG 1
 #define MEMDEBUGMASK 0x7fffff
-#define MEMDEBUGTEST 0x280000
+#define MEMDEBUGTEST 0x1ff000
 #define PICASSOIV_DEBUG_IO 0
 
 static bool memlogr = false;
@@ -102,6 +102,9 @@ struct gfxboard
 
 #define ISP4() (currprefs.rtgmem_type == PICASSOIV_Z2 || currprefs.rtgmem_type == PICASSOIV_Z3)
 
+// Picasso II: 8* 4x256 (1M) or 16* 4x256 (2M)
+// Piccolo: 8* 4x256 + 2* 16x256 (2M)
+
 static struct gfxboard boards[] =
 {
        {
index bfc1b9d4ca303530a36c45e47c56cfa3a32fd2cc..a060ff686e8a8a42b774f199d5d50fd434ff3721 100644 (file)
@@ -1,3 +1,7 @@
+
+#ifndef A2091_H
+#define A2091_H
+
 #ifdef A2091
 
 extern addrbank dmaca2091_bank;
@@ -35,3 +39,5 @@ extern int add_scsi_cd (int ch, int unitnum);
 extern int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly);
 
 #endif
+
+#endif /* A2091H */
index 9e4f6a17f2b37a890b41fc96d57c93a43552063e..dc902a299806ac96823c07533b0c5a90b31b9cb2 100644 (file)
@@ -1,4 +1,7 @@
 
+#ifndef BLKDEV_H
+#define BLKDEV_H
+
 #define DEVICE_SCSI_BUFSIZE (65536 - 1024)
 
 #define SCSI_UNIT_DISABLED -1
@@ -210,3 +213,5 @@ extern void blkdev_entergui (void);
 extern void blkdev_exitgui (void);
 
 bool filesys_do_disk_change (int, bool);
+
+#endif /* BLKDEV_H */
index 9dedd0a4fea5c9124433564664b31772fc53ec8f..660fba93aeefc0f5bcc5ebe0949dc2cd4228a276 100644 (file)
@@ -6,6 +6,9 @@
 * (c) 1995 Bernd Schmidt
 */
 
+#ifndef CUSTOM_H
+#define CUSTOM_H
+
 #include "machdep/rpt.h"
 
 /* These are the masks that are ORed together in the chipset_mask option.
@@ -85,7 +88,7 @@ extern unsigned int joy0dir, joy1dir;
 extern int joy0button, joy1button;
 
 extern void INTREQ (uae_u16);
-extern void INTREQ_0 (uae_u16);
+extern bool INTREQ_0 (uae_u16);
 extern void INTREQ_f (uae_u16);
 extern void send_interrupt (int num, int delay);
 extern uae_u16 INTREQR (void);
@@ -231,3 +234,5 @@ extern bool ispal (void);
 extern int current_maxvpos (void);
 extern struct chipset_refresh *get_chipset_refresh (void);
 extern void compute_framesync (void);
+
+#endif /* CUSTOM_H */
index 733f2150e1d751ef7223a1751c756442a0d6821f..78d483933d0593054630f4d513acae850166e99e 100644 (file)
@@ -110,9 +110,20 @@ STATIC_INLINE void set_cycles (unsigned long int x)
 #endif
 }
 
+STATIC_INLINE int current_hpos_safe (void)
+{
+    int hp = (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
+       return hp;
+}
+
 STATIC_INLINE int current_hpos (void)
 {
-    return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
+    int hp = current_hpos_safe ();
+       if (hp < 0 || hp >= 256) {
+               gui_message(_T("hpos = %d!?\n"), hp);
+               hp = 0;
+       }
+       return hp;
 }
 
 STATIC_INLINE bool cycles_in_range (unsigned long endcycles)
index e77c41f730a3f9b30c7eb9e60ad51ae0a7692e81..bdf625c910377b696fafbfbd6598628a0b8df631 100644 (file)
@@ -6,6 +6,9 @@
   * Copyright 1997 Bernd Schmidt
   */
 
+#ifndef FILESYS_H
+#define FILESYS_H
+
 struct hardfilehandle;
 
 #define MAX_HDF_CACHE_BLOCKS 128
@@ -146,3 +149,4 @@ extern void getchsgeometry (uae_u64 size, int *pcyl, int *phead, int *psectorspe
 extern void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int *phead, int *psectorspertrack);
 extern void getchspgeometry (uae_u64 total, int *pcyl, int *phead, int *psectorspertrack, bool idegeometry);
 
+#endif /* MEMORY_H */
index 82e58b00f81e145b7f8a5f1c1989d2d1c810eae9..bc997fa98b934d974c68f93240f866984b5b6560 100644 (file)
@@ -6,6 +6,9 @@
 * Copyright 1995 Bernd Schmidt
 */
 
+#ifndef MEMORY_H
+#define MEMORY_H
+
 extern void memory_reset (void);
 extern void a1000_reset (void);
 
@@ -440,3 +443,5 @@ extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
 
 extern uae_s32 getz2size (struct uae_prefs *p);
 extern ULONG getz2endaddr (void);
+
+#endif /* MEMORY_H */
index 7d03b36421ed16c18b723dd34195b2e359b4cebd..df515546a879f333270c374775f8a46579902f41 100644 (file)
@@ -7,6 +7,9 @@
 * Copyright 1995-2001 Bernd Schmidt
 */
 
+#ifndef OPTIONS_H
+#define OPTIONS_H
+
 #define UAEMAJOR 2
 #define UAEMINOR 7
 #define UAESUBREV 1
@@ -30,7 +33,7 @@ struct strlist {
 #define MAX_TOTAL_SCSI_DEVICES 8
 
 /* maximum number native input devices supported (single type) */
-#define MAX_INPUT_DEVICES 16
+#define MAX_INPUT_DEVICES 20
 /* maximum number of native input device's buttons and axles supported */
 #define MAX_INPUT_DEVICE_EVENTS 256
 /* 4 different customization settings */
@@ -664,3 +667,5 @@ extern struct uae_prefs currprefs, changed_prefs;
 
 extern int machdep_init (void);
 extern void machdep_free (void);
+
+#endif /* OPTIONS_H */
index d359f09d5f561fcdb9b7fab66b37d3c0657a4e01..c3f0ebddad7d86989081966ca8cb8a52f0a1bf34 100644 (file)
@@ -108,4 +108,4 @@ extern void tape_media_change (int unitnum, struct uaedev_config_info*);
 #define SCSI_STATUS_RESERVATION_CONFLICT   0x18
 #define SCSI_STATUS_COMMAND_TERMINATED     0x22
 #define SCSI_STATUS_QUEUE_FULL             0x28
-#define SCSI_STATUS_ACA_ACTIVE             0x30
\ No newline at end of file
+#define SCSI_STATUS_ACA_ACTIVE             0x30
diff --git a/include/uaenative.h b/include/uaenative.h
new file mode 100644 (file)
index 0000000..b06af08
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* UAE Native Interface (UNI)
+*
+* Copyright 2013-2014 Frode Solheim
+*/
+
+#ifndef _UAE_UAENATIVE_H_
+#define _UAE_UAENATIVE_H_
+
+#ifdef WITH_UAENATIVE
+
+#if defined(_WIN32) || defined(WINDOWS)
+
+    #define UNIAPI __declspec(dllimport)
+    #define UNICALL __cdecl
+
+#else // _WIN32 not defined
+
+    #define UNIAPI
+    #define UNICALL
+
+#endif
+
+#include "uni_common.h"
+
+#define UNI_FLAG_ASYNCHRONOUS 1
+#define UNI_FLAG_COMPAT 2
+#define UNI_FLAG_NAMED_FUNCTION 4
+
+uae_u32 uaenative_open_library(TrapContext *context, int flags);
+uae_u32 uaenative_get_function(TrapContext *context, int flags);
+uae_u32 uaenative_call_function(TrapContext *context, int flags);
+uae_u32 uaenative_close_library(TrapContext *context, int flags);
+
+void *uaenative_get_uaevar(void);
+
+void uaenative_install ();
+uaecptr uaenative_startup (uaecptr resaddr);
+
+/* This function must return a list of directories to look for native
+ * libraries in. The returned list must be NULL-terminated, and must not
+ * be de-allocated. */
+const TCHAR **uaenative_get_library_dirs(void);
+
+#endif // WITH_UAENATIVE
+
+#endif // _UAE_UAENATIVE_H_
diff --git a/include/uni_common.h b/include/uni_common.h
new file mode 100644 (file)
index 0000000..47487ad
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* UAE Native Interface (UNI)
+*
+* Copyright 2013-2014 Frode Solheim
+*/
+
+#ifndef _UAE_UNI_COMMON_H_
+#define _UAE_UNI_COMMON_H_
+
+#define UNI_VERSION 1
+
+#ifndef UNI_MIN_VERSION
+// MIN_UNI_VERSION decides which callback functions are declared available.
+// The default, unless overriden is to required the current UNI version.
+#define UNI_MIN_VERSION UNI_VERSION
+#endif
+
+#define UNI_ERROR_NOT_ENABLED            0x70000001
+#define UNI_ERROR_INVALID_LIBRARY        0x70000002
+#define UNI_ERROR_INVALID_FUNCTION       0x70000002
+#define UNI_ERROR_FUNCTION_NOT_FOUND     0x70000003
+#define UNI_ERROR_LIBRARY_NOT_FOUND      0x70000004
+#define UNI_ERROR_INVALID_FLAGS          0x70000005
+#define UNI_ERROR_COULD_NOT_OPEN_LIBRARY 0x70000006
+#define UNI_ERROR_ILLEGAL_LIBRARY_NAME   0x70000007
+#define UNI_ERROR_LIBRARY_TOO_OLD        0x70000008
+#define UNI_ERROR_INIT_FAILED            0x70000009
+#define UNI_ERROR_INTERFACE_TOO_OLD      0x7000000a
+
+// these errors are only return from the Amiga-side uni wrappers
+#define UNI_ERROR_AMIGALIB_NOT_OPEN      0x71000000
+
+// On all current platforms, char, short and int short be 1, 2 and 4 bytes
+// respectively, so we just use these simple types.
+
+typedef char           uni_char;
+typedef unsigned char  uni_uchar;
+typedef short          uni_short;
+typedef unsigned short uni_ushort;
+typedef int            uni_long;
+typedef unsigned int   uni_ulong;
+
+typedef int (UNICALL *uni_version_function)();
+typedef void * (UNICALL *uni_resolve_function)(uni_ulong ptr);
+typedef const uni_char * (UNICALL *uni_uae_version_function)(void);
+
+struct uni {
+    uni_long d1;
+    uni_long d2;
+    uni_long d3;
+    uni_long d4;
+    uni_long d5;
+    uni_long d6;
+    uni_long d7;
+    uni_long a1;
+    uni_long a2;
+    uni_long a3;
+    uni_long a4;
+    uni_long a5;
+    uni_long a7;
+
+#if UNI_VERSION >= 2
+    // add new struct entries for version 2 here
+#endif
+
+#ifdef CPUEMU_0  // UAE
+    uni_long result;
+    uni_long error;
+    uni_ulong function;
+    uni_ulong library;
+    void *native_function;
+    void *uaevar_compat;
+    int flags;
+    uaecptr task;
+#endif
+};
+
+#endif // _UAE_UNI_COMMON_H_
index 7189e86487cd694b390302cdee98f188fb4da991..e73b5cc968dc6bdc6acde0347b8a07e3e9c2f722 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -56,6 +56,7 @@
 #include "gayle.h"
 #include "gfxboard.h"
 #include "luascript.h"
+#include "uaenative.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -1004,6 +1005,9 @@ void virtualdevice_init (void)
 #if defined (BSDSOCKET)
        bsdlib_install ();
 #endif
+#ifdef WITH_UAENATIVE
+       uaenative_install ();
+#endif
 }
 
 static int real_main2 (int argc, TCHAR **argv)
index 4147f808d6c46e7cbccb2bcf553825e89e295dee..bae8ff2573c8b4c1bf8984cb2bcbbee28920d0dd 100644 (file)
@@ -1266,27 +1266,27 @@ static int patch_residents (uae_u8 *kickmemory, int size)
        // "scsi.device", "carddisk.device", "card.resource" };
        uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000;
 
-       if (currprefs.cs_mbdmac == 2)
-               residents[0] = NULL;
-       for (i = 0; i < size - 100; i++) {
-               if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
-                       uaecptr addr;
-                       addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
-                       if (addr != i + base)
-                               continue;
-                       addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
-                       if (addr >= base && addr < base + size) {
-                               j = 0;
-                               while (residents[j]) {
-                                       if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
-                                               TCHAR *s = au (residents[j]);
-                                               write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base);
-                                               xfree (s);
-                                               kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
-                                               patched++;
-                                               break;
+       if (currprefs.cs_mbdmac != 2) {
+               for (i = 0; i < size - 100; i++) {
+                       if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
+                               uaecptr addr;
+                               addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
+                               if (addr != i + base)
+                                       continue;
+                               addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
+                               if (addr >= base && addr < base + size) {
+                                       j = 0;
+                                       while (residents[j]) {
+                                               if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
+                                                       TCHAR *s = au (residents[j]);
+                                                       write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base);
+                                                       xfree (s);
+                                                       kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
+                                                       patched++;
+                                                       break;
+                                               }
+                                               j++;
                                        }
-                                       j++;
                                }
                        }
                }
index 874c0696be2f97d3b40495cb261c3eaa0ed406d1..8a7dc5a34ff02704e4463f2c3c1ac35cbf6958c2 100644 (file)
@@ -986,7 +986,7 @@ static void sortobjects (struct didata *did)
 #define RDP_DEVICE1 _T("\\??\\Root#")
 #define RDP_DEVICE2 _T("\\\\?\\Root#")
 
-static int rdpdevice(TCHAR *buf)
+static int rdpdevice(const TCHAR *buf)
 {
        if (!_tcsncmp (RDP_DEVICE1, buf, _tcslen (RDP_DEVICE1)))
                return 1;
@@ -1392,11 +1392,11 @@ static void dumphidbuttoncaps (PHIDP_BUTTON_CAPS pcaps, int size)
        }
 }
 
-static void dumphidcaps (struct didata *did)
+static void dumphidcaps (struct didata *did, int cnt)
 {
        HIDP_CAPS caps = did->hidcaps;
 
-       write_log (_T("\n******** USB HID: '%s'\n"), did->name);
+       write_log (_T("\n******** %d USB HID: '%s'\n"), cnt, did->name);
        write_log (_T("Usage: %04x\n"), caps.Usage);
        write_log (_T("UsagePage: %04x\n"), caps.UsagePage);
        write_log (_T("InputReportByteLength: %u\n"), caps.InputReportByteLength);
@@ -1500,7 +1500,7 @@ static bool initialize_rawinput (void)
        if (MAX_RAW_KEYBOARD > 0 && rnum_kb > MAX_RAW_KEYBOARD)
                rnum_kb = MAX_RAW_KEYBOARD;
 
-
+       write_log (_T("HID device check:\n"));
        for (int rawcnt = 0; rawcnt < gotnum; rawcnt++) {
                HANDLE h = ridl[rawcnt].hDevice;
                int type = ridl[rawcnt].dwType;
@@ -1533,28 +1533,44 @@ static bool initialize_rawinput (void)
                        } else
                                continue;
 
-                       if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1)
+                       if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1) {
+                               write_log (_T("%p RIDI_DEVICENAME failed\n"), h);
                                continue;
-                       if (vtmp >= bufsize)
+                       }
+                       if (vtmp >= bufsize) {
+                               write_log (_T("%p RIDI_DEVICENAME too big %d\n"), h, vtmp);
                                continue;
-                       if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, buf1, &vtmp) == -1)
+                       }
+                       if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, buf1, &vtmp) == -1) {
+                               write_log (_T("%p RIDI_DEVICENAME %d failed\n"), h, vtmp);
                                continue;
+                       }
 
                        rdi = (PRID_DEVICE_INFO)buf2;
                        memset (rdi, 0, sizeof (RID_DEVICE_INFO));
                        rdi->cbSize = sizeof (RID_DEVICE_INFO);
-                       if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, NULL, &vtmp) == -1)
+                       if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, NULL, &vtmp) == -1) {
+                               write_log (_T("%p RIDI_DEVICEINFO failed\n"), h);
                                continue;
-                       if (vtmp >= bufsize)
+                       }
+                       if (vtmp >= bufsize) {
+                               write_log (_T("%p RIDI_DEVICEINFO too big %d\n"), h, vtmp);
                                continue;
-                       if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, buf2, &vtmp) == -1)
+                       }
+                       if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, buf2, &vtmp) == -1) {
+                               write_log (_T("%p RIDI_DEVICEINFO %d failed\n"), h, vtmp);
                                continue;
+                       }
+
+                       write_log (_T("%p %04x/%04x (%d/%d)\n"), h, rdi->hid.dwVendorId, rdi->hid.dwProductId, rdi->hid.usUsage, rdi->hid.usUsagePage);
 
                        if (type == RIM_TYPEMOUSE) {
                                if (rdpdevice (buf1))
                                        continue;
-                               if (num_mouse >= MAX_INPUT_DEVICES - 1) /* leave space for Windows mouse */
+                               if (num_mouse >= MAX_INPUT_DEVICES - 1)  {/* leave space for Windows mouse */
+                                       write_log (_T("Too many mice\n"));
                                        continue;
+                               }
                                did += num_mouse;
                                num_mouse++;
                                rmouse++;
@@ -1562,8 +1578,10 @@ static bool initialize_rawinput (void)
                        } else if (type == RIM_TYPEKEYBOARD) {
                                if (rdpdevice (buf1))
                                        continue;
-                               if (num_keyboard >= MAX_INPUT_DEVICES)
+                               if (num_keyboard >= MAX_INPUT_DEVICES) {
+                                       write_log (_T("Too many keyboards\n"));
                                        continue;
+                               }
                                did += num_keyboard;
                                num_keyboard++;
                                rkb++;
@@ -1571,16 +1589,26 @@ static bool initialize_rawinput (void)
                        } else if (type == RIM_TYPEHID) {
                                if (rdpdevice (buf1))
                                        continue;
-                               if (rdi->hid.usUsage != 4 && rdi->hid.usUsage != 5)
+                               if (rdi->hid.usUsage != 4 && rdi->hid.usUsage != 5) {
+                                       write_log (_T("RAWHID: Usage not 4 or 5 (%d)\n"), rdi->hid.usUsage);
                                        continue;
-                               if (rdi->hid.usUsagePage >= 0xff00) // vendor specific
+                               }
+                               if (rdi->hid.usUsagePage >= 0xff00) { // vendor specific
+                                       write_log (_T("RAWHID: Ignored vendor specific %04x\n"), rdi->hid.usUsagePage);
                                        continue;
+                               }
                                for (i = 0; hidnorawinput[i].vid; i++) {
                                        if (rdi->hid.dwProductId == hidnorawinput[i].pid && rdi->hid.dwVendorId == hidnorawinput[i].vid)
                                                break;
                                }
-                               if (hidnorawinput[i].vid || num_joystick >= MAX_INPUT_DEVICES)
+                               if (hidnorawinput[i].vid) {
+                                       write_log (_T("RAWHID: blacklisted\n"));
                                        continue;
+                               }
+                               if (num_joystick >= MAX_INPUT_DEVICES) {
+                                       write_log (_T("RAWHID: too many devices\n"));
+                                       continue;
+                               }
                                did += num_joystick;
                                num_joystick++;
                                rhid++;
@@ -1675,7 +1703,7 @@ static bool initialize_rawinput (void)
                                        if (HidP_GetCaps (did->hidpreparseddata, &did->hidcaps) == HIDP_STATUS_SUCCESS) {
                                                PHIDP_BUTTON_CAPS bcaps;
                                                USHORT size = did->hidcaps.NumberInputButtonCaps;
-                                               dumphidcaps (did);
+                                               dumphidcaps (did, rawcnt);
                                                bcaps = xmalloc (HIDP_BUTTON_CAPS, size);
                                                if (HidP_GetButtonCaps (HidP_Input, bcaps, &size, did->hidpreparseddata) == HIDP_STATUS_SUCCESS) {
                                                        dumphidbuttoncaps (bcaps, size);
@@ -3164,6 +3192,14 @@ static void release_keys (void)
        rawprevkey = -1;
 }
 
+static void flushmsgpump (void)
+{
+       MSG msg;
+       while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
+               TranslateMessage (&msg);
+               DispatchMessage (&msg);
+       }
+}
 
 static int acquire_kb (int num, int flags)
 {
@@ -3172,6 +3208,7 @@ static int acquire_kb (int num, int flags)
        if (num < 0) {
                doregister_rawinput ();
                if (currprefs.keyboard_leds_in_use) {
+                       //write_log (_T("***********************acquire_kb_led\n"));
                        if (!currprefs.win32_kbledmode) {
                                if (DefineDosDevice (DDD_RAW_TARGET_PATH, _T("Kbd"), _T("\\Device\\KeyboardClass0"))) {
                                        kbhandle = CreateFile (_T("\\\\.\\Kbd"), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
@@ -3189,7 +3226,8 @@ static int acquire_kb (int num, int flags)
                                originalleds = oldleds;
                                //write_log (_T("stored %08x -> %08x\n"), originalleds, newleds);
                        }
-                       update_leds ();
+                       set_leds (newleds);
+                       flushmsgpump ();
                }
                return 1;
        }
@@ -3219,10 +3257,12 @@ static void unacquire_kb (int num)
        if (num < 0) {
                doregister_rawinput ();
                if (currprefs.keyboard_leds_in_use) {
+                       //write_log (_T("*********************** unacquire_kb_led\n"));
                        if (originalleds != -1) {
                                //write_log (_T("restored %08x -> %08x\n"), oldleds, originalleds);
                                set_leds (originalleds);
                                originalleds = -1;
+                               flushmsgpump ();
                        }
                        if (kbhandle != INVALID_HANDLE_VALUE) {
                                CloseHandle (kbhandle);
index abd531ad27d9081140b2478abcdc2a695c4a3be6..961e208348f3e9ef6b1297400d56e552f6f1574b 100644 (file)
@@ -75,9 +75,24 @@ struct uae_driveinfo {
 * - block 0 is zeroed
 */
 
-int harddrive_dangerous, do_rdbdump;
+int harddrive_dangerous = 0x1234dead;
+int do_rdbdump;
 static struct uae_driveinfo uae_drives[MAX_FILESYSTEM_UNITS];
 
+#if 0
+static void fixdrive (struct hardfiledata *hfd)
+{
+       uae_u8 data[512];
+       struct zfile *zf = zfile_fopen (_T("d:\\amiga\\hdf\\a500supradrive.hdf"), _T("rb"));
+       for (int i = 0; i < 0x30000 / 512; i++) {
+               zfile_fread (data, 1, 512, zf);
+               hdf_write (hfd, data, i * 512, 512);
+       }
+       zfile_fclose (zf);
+
+}
+#endif
+
 static int isnomediaerr (DWORD err)
 {
        if (err == ERROR_NOT_READY ||
@@ -624,6 +639,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
                                goto end;
                        if (!DeviceIoControl (h, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &r, NULL))
                                write_log (_T("WARNING: '%s' FSCTL_ALLOW_EXTENDED_DASD_IO returned %d\n"), name, GetLastError ());
+
                        //queryidentifydevice (hfd);
                        _tcsncpy (hfd->vendor_id, udi->vendor_id, 8);
                        _tcsncpy (hfd->product_id, udi->product_id, 16);
@@ -672,6 +688,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
                        }
                        hfd->handle_valid = HDF_HANDLE_WIN32;
                        hfd->emptyname = my_strdup (name);
+                       //fixdrive (hfd);
                } else {
                        hfd->flags = HFD_FLAGS_REALDRIVE;
                        hfd->drive_empty = -1;
index 7a01da22343504995de57bd405be336aaab3d63b..de038003d7fa1758e25a0b76ad594c623286e5bb 100644 (file)
@@ -16,6 +16,7 @@
 #define __i386__
 #define WINDOWS
 #define ZLIB_WINAPI
+#define PACKAGE_STRING "WinUAE"
 
 #ifndef UAE_MINI
 
@@ -77,6 +78,7 @@
 #define RETROPLATFORM /* Cloanto RetroPlayer support */
 #define WITH_CHD
 #define WITH_LUA /* lua scripting */
+#define WITH_UAENATIVE
 
 #else
 
index 45b91d92163eb134a6322253c338a88d591f21f6..c7ead3bec9a648f9a757635512904716d1362519 100644 (file)
@@ -6210,6 +6210,40 @@ void fpux_restore (int *v)
 #endif
 }
 
+struct winuae  //this struct is put in a6 if you call
+       //execute native function
+{
+       HWND amigawnd;    //adress of amiga Window Windows Handle
+       unsigned int changenum;   //number to detect screen close/open
+       unsigned int z3offset;    //the offset to add to acsess Z3 mem from Dll side
+};
+
+void *uaenative_get_uaevar (void)
+{
+       static struct winuae uaevar;
+#ifdef _WIN32
+    uaevar.amigawnd = hAmigaWnd;
+#endif
+    uaevar.z3offset = (uae_u32)get_real_address (0x10000000) - 0x10000000;
+    return &uaevar;
+}
+
+const TCHAR **uaenative_get_library_dirs (void)
+{
+       static const TCHAR **nats;
+       static TCHAR *path;
+
+       if (nats == NULL)
+               nats = xcalloc (const TCHAR*, 3);
+       if (path == NULL) {
+               path = xcalloc (TCHAR, MAX_DPATH);
+               _tcscpy (path, start_path_data);
+               _tcscat (path, _T("plugins"));
+       }
+       nats[0] = start_path_data;
+       nats[1] = path;
+       return nats;
+}
 
 typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);
 
index bcd8f033ea8197a998ad881cd2fc77c482b5db35..4f4bbad6f02af54812596e88eeb2c7760b0232ff 100644 (file)
 #define LANG_DLL 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("4")
+#define WINUAEBETA _T("5")
 #else
 #define WINUAEBETA _T("")
 #endif
-#define WINUAEDATE MAKEBD(2014, 1, 18)
+#define WINUAEDATE MAKEBD(2014, 2, 2)
 #define WINUAEEXTRA _T("")
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index d22f82c8fb5d7036c77f09ccbfbcab97e8553ee2..9e4cb80396a2fb873b0f04cb4ea1f30250732d34 100644 (file)
@@ -1,6 +1,6 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
+VisualStudioVersion = 12.0.30110.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winuae", "winuae_msvc.vcxproj", "{4ADAA943-1AC8-4FB5-82E5-4FB753B6C2DA}"
 EndProject
@@ -397,7 +397,6 @@ Global
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|Mixed Platforms.Build.0 = Debug|x86
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|Win32.ActiveCfg = Debug|x86
-               {BE211CE1-3955-4674-A664-5038FC791980}.Debug|Win32.Build.0 = Debug|x86
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|x64.ActiveCfg = Debug|x86
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|x86.ActiveCfg = Debug|x86
                {BE211CE1-3955-4674-A664-5038FC791980}.Debug|x86.Build.0 = Debug|x86
index 4fe2386bfff21733114e2a5389c7625b10b54ef2..b0e677f91caf5d54d71a94d00b8f0f9055fb9cda 100644 (file)
       <WarningLevel>Level3</WarningLevel>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <CallingConvention>StdCall</CallingConvention>
+      <CallingConvention>FastCall</CallingConvention>
       <CompileAs>Default</CompileAs>
       <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <EnablePREfast>false</EnablePREfast>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>.\Debug/winuae.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
     <ClCompile Include="..\..\isofs.cpp" />
     <ClCompile Include="..\..\luascript.cpp" />
     <ClCompile Include="..\..\qemuvga\cirrus_vga.cpp" />
+    <ClCompile Include="..\..\qemuvga\lsi53c895a.cpp" />
     <ClCompile Include="..\..\qemuvga\qemuuaeglue.cpp" />
     <ClCompile Include="..\..\qemuvga\vga.cpp" />
     <ClCompile Include="..\..\scsitape.cpp" />
     <ClCompile Include="..\..\slirp\udp.cpp" />
     <ClCompile Include="..\..\specialmonitors.cpp" />
     <ClCompile Include="..\..\statusline.cpp" />
+    <ClCompile Include="..\..\uaenative.cpp" />
     <ClCompile Include="..\ahidsound_dsonly.cpp" />
     <ClCompile Include="..\ahidsound_new.cpp" />
     <ClCompile Include="..\avioutput.cpp" />
index 1cf15a3b8006ff54730bc88b0158c6afce66ad77..c97d11ed1514cb55c27d95ec97c21e79484b0716 100644 (file)
     <ClCompile Include="..\..\cpuemu_13.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\uaenative.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\qemuvga\lsi53c895a.cpp">
+      <Filter>qemu</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
index 1cc917a38d631a0fb11a216f590505d451cb73c7..ac5217d78ff7bb1646fbf4476dc0f30197c57014 100644 (file)
@@ -1,6 +1,66 @@
 
+1 -> 0: 0,1FE,1FE,1FE,..
+1 -> 1: 0,1FE,0,1FE,0,..
+1 -> 2: 0,1FE,70,1FE,70,.. (C-)
+1 -> 9: 0,1FE,0,74,0,74,.. (DA)
+1 -> B: 0,1FE,70,0,74,70,0,74,70,0,74,.. (ACD)
+1 -> C: 0,1FE,72,74,70,72,74,70,72,.. (CBA)
+1 -> D: 0,1FE,72,74,70,72,74,70,72,.. (CBA)
+1 -> E: 0,1FE,70,70,70,70,.. (C)
+1 -> F: 0,1FE,70,70,74,70,70,70,74,70,70,70,74,.. (CCCA)
+
 - restore only single input target to default.
 
+- More than one horizontal DDFSTRT-DDFSTOP window is now accurately emulated without requiring any hacks.
+  Random garbage between display windows is also gone. (Subtle Shades / Nuance)
+- Removed some more obsolete variables from display emulation.
+- Saigon Megademo fix got accidentally broken in b2.
+- 260b17 "strange right edge overscan display shift" optional hack removed, new delay/shift register
+  behavior creates identical output automatically simply by reseting delay counter (hpos counter) at the
+  end of scanline. NOTE: Some programs with large overscan can now have small graphics corruption in right
+  border (gap in graphics), it is not a bug, it is accurate emulation. (For example Back in Bizness / 2000AD)
+- Some OCS only programs may now have graphics corruption in ECS mode (if bitplane DMA crosses scanlines),
+  this is also not a bug, real hardware would show even worse corruption. Someday this will be more accurately emulated.
+- Agnus vpos counter increase delayed by 1 cycle. Fixes Hit the Road / Flash Production "Floffy2" part.
+- Keyboard leds as power/floppy/etc indicators are now properly restored back to original state when
+  keyboard input is not active, changing led config on the fly also works now.
+- Exiting GUI with close button or ALT-F4 didn't save GUI position.
+
+Beta 3:
+
+- Sprites near left border had strange corruption (b1)
+- "toscr_nbits > 16" error in some situations (b1)
+- "Modified interrupt delays" b1 change was bad, sometimes interrupt request was kept active
+  causing spurious interrupts (which caused crashes).
+- New autoresolution selection was not loaded correctly from config file.
+- Blitter final D write don't increase "nasty" count. (Which makes sense, blit is already
+  finished, blitbusy bit was cleared 2 cycles ago)
+- Removed most BPLxDAT related hacks, they become obsolete after b2 BPLCON1 update (it also changed
+  how data gets moved to shift registers). May introduce new glitches and if it does, it needs
+  correct emulation updates, not hacks.
+
+Beta 2:
+
+- BPLCON1 mid scan line modifications now should match real hardware 100%.
+  This was very big change, old emulation was functionally close enough but very far from real
+  hardware behavior. Old code couldn't emulate some side-effects correctly.
+
+- Partial/full scanline based mode ("SPEEDUP") is again used more regularly, "is it safe to use" check
+  got partially broken during 2.7.0 betas. It is also more optimal in AGA 32/64-bit fetch modes.
+- AGA border sprite in right border and 2x or 4x horizontal sprite pixels (vs bitplane pixels): sprite's
+  rightmost pixel(s) were missing.
+- Superhires and top or bottom border sprite: graphics garbage was seen in border area, memory
+  corruption was also possible in some situations.
+- Magic mouse + mousehack mode now always stops keyboard input when mouse is outside of emulation
+  window, even if window still has focus.
+- 68020/030 CAAR register preserves also all reserved bits.
+- Disable JIT if config has 68000/010 CPU and non-zero JIT cache size.
+- 68020 CE broke interrupt state fetch, interrupt didn't clear if write to INTREQ was immediately
+  followed by RTE. (b1)
+- Does not anymore require SSE2 capable CPU (b1 did)
+
+Beta 1:
+
 Lots of small blitter, copper and CPU timing adjustments. (Thanks to amilo3438 for collecting huge amounts
 of demo test cases). Lots of logic analyzer tests done during last few weeks.
 
index 10991a55422ec3269b116de9272a2e77c983d80b..a10e7bbc8e841a7e5b9d38031fc199094d1b433a 100644 (file)
@@ -417,7 +417,7 @@ static TCHAR *writets (void)
        _stprintf (p, _T("%03d"), tb.millitm);
        p += _tcslen (p);
        if (vsync_counter != 0xffffffff)
-               _stprintf (p, _T(" [%d %03d%s%03d]"), vsync_counter, current_hpos (), lof_store ? _T("-") : _T("="), vpos);
+               _stprintf (p, _T(" [%d %03d%s%03d]"), vsync_counter, current_hpos_safe (), lof_store ? _T("-") : _T("="), vpos);
        _tcscat (p, _T(": "));
        return out;
 }
@@ -498,6 +498,9 @@ void write_log (const TCHAR *format, ...)
 
        premsg ();
 
+       if (!_tcsicmp (format, _T("*")))
+               count = 0;
+
        EnterCriticalSection (&cs);
        va_start (parms, format);
        bufp = buffer;
index 1ddfb6733c049d36930639ac7f0871b6c7a0a44e..0c30a8e250a141ba7124f2c14b9761d54e94ac01 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef MEMORY_H
-#define MEMORY_H
+#ifndef QMEMORY_H
+#define QMEMORY_H
 
 #ifndef CONFIG_USER_ONLY
 
@@ -899,4 +899,5 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
 
 #endif
 
-#endif
+#endif /* QMEMORY */
+
diff --git a/uaenative.cpp b/uaenative.cpp
new file mode 100644 (file)
index 0000000..efeda72
--- /dev/null
@@ -0,0 +1,851 @@
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* UAE Native Interface (UNI) - uaenative.library
+*
+* Copyright 2013-2014 Frode Solheim. Amiga-side library sample code
+* provided by Toni Wilen.
+*
+* TODO: Handling UAE reset and shutdown better. When resetting the Amiga,
+* all opened native libraries should be closed, and all async call threads
+* should be stopped.
+*/
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#ifdef WITH_UAENATIVE
+
+#include <stdlib.h>
+#include "options.h"
+#include "memory.h"
+#include "custom.h"
+#include "newcpu.h"
+#include "traps.h"
+#include "autoconf.h"
+#include "execlib.h"
+#include "threaddep/thread.h"
+#include "native2amiga.h"
+#include "events.h"
+#include "uaenative.h"
+#include "fsdb.h"
+
+#if defined(FSUAE) && defined(WINDOWS)
+#define _WIN32
+#endif
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
+static double syncdivisor;
+
+#define SIGBIT 8 // SIGB_DOS
+
+// the function prototype for the callable native functions
+typedef uae_s32 (UNICALL *uae_uni_native_function)(struct uni *uni);
+
+// the function prototype for the callable native functions (old style)
+typedef uae_u32 (UNICALL *uae_uni_native_compat_function)(uae_u32, uae_u32,
+        uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32,
+        uae_u32, uae_u32, uae_u32, void *, uae_u32, void *);
+
+// the function prototype for the native library's uni_init function
+typedef int (UNICALL *uni_init_function)(void);
+
+struct library_data {
+    void *dl_handle;
+    uae_thread_id thread_id;
+    uae_sem_t empty_count;
+    uae_sem_t full_count;
+    int thread_stop_flag;
+    struct uni *uni;
+};
+
+struct uni_handle {
+    struct library_data *library;
+    void *function;
+};
+
+static uni_handle *g_handles = NULL;
+static int g_allocated_handles = 0;
+static int g_max_handle = -1;
+
+#if defined (_WIN32)
+    #define OS_EXTENSION _T("-windows")
+    #define FILE_EXTENSION _T(".dll")
+#elif defined (LINUX)
+    #define OS_EXTENSION _T("-linux")
+    #define FILE_EXTENSION _T(".so")
+#elif defined (MACOSX)
+    #define OS_EXTENSION _T("-macosx")
+    #define FILE_EXTENSION _T(".dylib")
+#elif defined (FREEBSD)
+    #define OS_EXTENSION _T("-freebsd")
+    #define FILE_EXTENSION _T(".so")
+#elif defined (OPENBSD)
+    #define OS_EXTENSION _T("-openbsd")
+    #define FILE_EXTENSION _T(".so")
+#else
+    #define OS_EXTENSION _T("-unknown")
+    #define FILE_EXTENSION _T(".unknown")
+#endif
+
+#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+    #define ARCH_EXTENSION _T("-x86-64")
+#elif defined(__i386__) || defined (_M_IX86)
+    #define ARCH_EXTENSION _T("-x86")
+#elif defined(__ppc__)
+    #define ARCH_EXTENSION _T("-ppc")
+#else
+    #define ARCH_EXTENSION _T("-unknown")
+#endif
+
+static int UNICALL uni_version(void)
+{
+    return UNI_VERSION;
+}
+
+static void * UNICALL uni_resolve(uae_u32 ptr)
+{
+    void *result = get_real_address (ptr);
+    //printf ("UNI: resolve address 0x%08x -> %p\n", ptr, result);
+    return result;
+}
+
+static const char * UNICALL uni_uae_version(void)
+{
+    // A standard GNU macro with a string containing program name and
+    // version, e.g. "WinUAE 2.7.0" or "FS-UAE 2.3.16dev".
+    return PACKAGE_STRING;
+}
+
+static void free_library_data(struct library_data *library_data) {
+    if (library_data->empty_count) {
+        uae_sem_destroy(&library_data->empty_count);
+    }
+    if (library_data->full_count) {
+        uae_sem_destroy(&library_data->full_count);
+    }
+    free(library_data);
+}
+
+static uae_u32 register_handle(library_data *library_data, void *function)
+{
+    int index = -1;
+    if (g_max_handle >= g_allocated_handles - 1) {
+        // Entries above g_max_handle are assumed to be uninitialized,
+        // but unused/"freed" entries below g_max_handle must be zeroed.
+        // Try to find a reusable entry before allocating more space.
+        for (int i = 0; i < g_max_handle; i++) {
+            if (g_handles[i].library == NULL && g_handles[i].function == NULL) {
+                index = i;
+                break;
+            }
+        }
+        if (index == -1) {
+            int new_count = g_allocated_handles * 2;
+            if (new_count == 0) {
+                new_count = 128;
+            }
+            write_log("uni: allocating memory for %d handles\n", new_count);
+            g_handles = (uni_handle *) realloc(g_handles,
+                                new_count * sizeof(struct uni_handle));
+            g_allocated_handles = new_count;
+        }
+    }
+
+    if (index == -1) {
+        index = g_max_handle + 1;
+        g_max_handle = index;
+    }
+
+    g_handles[index].library = library_data;
+    g_handles[index].function = function;
+
+    // valid handles start from 0x80000000, anything below is error code
+    return (uae_u32) 0x80000000 + (uae_u32) index;
+}
+
+static TCHAR *get_native_library_path (const TCHAR *library_name)
+{
+    write_log (_T("uni: find_native_library %s\n"), library_name);
+    TCHAR path[PATH_MAX];
+    const TCHAR **library_dirs = uaenative_get_library_dirs ();
+
+    for (const TCHAR **dir = library_dirs; *dir != NULL; dir++) {
+        // name must already have been checked to not contain anything
+        // to allow access to parent directories.
+        _sntprintf (path, PATH_MAX, _T("%s%s%s"), *dir, library_name,
+                OS_EXTENSION ARCH_EXTENSION FILE_EXTENSION);
+        write_log (_T("uni: checking %s\n"), path);
+        if (my_existsfile (path)) {
+            return my_strdup (path);
+        }
+#ifdef _WIN32
+        // for compatibility with existing WinUAE native interface
+        _sntprintf (path, PATH_MAX, _T("%s%s.dll"), *dir, library_name);
+        write_log (_T("uni: checking %s\n"), path);
+        if (my_existsfile (path)) {
+            return my_strdup (path);
+        }
+#endif
+    }
+    return NULL;
+}
+
+static void *dl_symbol(void *dl, const char *name)
+{
+    if (dl == NULL) {
+        return NULL;
+    }
+#ifdef _WIN32
+    return (void *) GetProcAddress ((HINSTANCE) dl, name);
+#else
+    return dlsym (dl, name);
+#endif
+}
+
+static void dl_close(void *dl)
+{
+#ifdef _WIN32
+    FreeLibrary ((HMODULE) dl);
+#else
+    dlclose (dl);
+#endif
+}
+
+static void set_library_globals(void *dl)
+{
+    void *address;
+
+    address = dl_symbol(dl, "uni_version");
+    if (address) *((uni_version_function *) address) = &uni_version;
+
+    address = dl_symbol(dl, "uni_resolve");
+    if (address) *((uni_resolve_function *) address) = &uni_resolve;
+
+    address = dl_symbol(dl, "uni_uae_version");
+    if (address) *((uni_uae_version_function *) address) = &uni_uae_version;
+}
+
+static uae_u32 open_library (const char *name, uae_u32 min_version)
+{
+    syncdivisor = (3580000.0 * CYCLE_UNIT) / (double) syncbase;
+
+    for (const char *c = name; *c; c++) {
+        if (*c == '/' || *c == '\\' || *c == ':') {
+            return UNI_ERROR_ILLEGAL_LIBRARY_NAME;
+        }
+    }
+
+    TCHAR *tname = au (name);
+    write_log (_T("uni: open native library '%s'\n"), tname);
+    TCHAR *path = get_native_library_path (tname);
+    free (tname);
+    if (path == NULL) {
+        write_log(_T("uni: library not found\n"));
+        return UNI_ERROR_LIBRARY_NOT_FOUND;
+    }
+
+    write_log (_T("uni: found library at %s - opening\n"), path);
+#ifdef _WIN32
+    void *dl = LoadLibrary (path);
+#else
+    void *dl = dlopen (path, RTLD_NOW);
+#endif
+    free(path);
+    if (dl == NULL) {
+        write_log (_T("uni: error opening library errno %d\n"), errno);
+        return UNI_ERROR_COULD_NOT_OPEN_LIBRARY;
+    }
+
+    // FIXME: check min version
+
+    set_library_globals(dl);
+
+    void *function_address = dl_symbol(dl, "uni_init");
+    if (function_address) {
+        int error = ((uni_init_function) function_address)();
+        if (error) {
+            dl_close(dl);
+            return error;
+        }
+    }
+
+    struct library_data *library_data = (struct library_data *) malloc(
+            sizeof(struct library_data));
+    memset(library_data, 0, sizeof(struct library_data));
+    library_data->dl_handle = dl;
+
+    uae_u32 handle = register_handle (library_data, NULL);
+    write_log(_T("uni: opened library %08x (%p)\n"), handle, dl);
+    return handle;
+}
+
+uae_u32 uaenative_open_library (TrapContext *context, int flags)
+{
+    if (!currprefs.native_code) {
+        write_log(_T("uni: tried to open native library, but native code ")
+                  _T("is not enabled\n"));
+        return UNI_ERROR_NOT_ENABLED;
+    }
+
+    uaecptr name;
+    uae_u32 min_version;
+    if (flags & UNI_FLAG_COMPAT) {
+        name = m68k_areg (regs, 0);
+        min_version = 0;
+    }
+    else {
+        name = m68k_areg (regs, 1);
+        min_version = m68k_dreg (regs, 0);
+    }
+
+    uae_u32 result = open_library (
+        (const char *) get_real_address (name), min_version);
+
+    if ((flags & UNI_FLAG_COMPAT) && !(result & 0x80000000)) {
+        // error opening library, return 0 for error in compatibility mode
+        return 0;
+    }
+    return result;
+}
+
+static struct library_data *get_library_data_from_handle (uae_u32 handle)
+{
+    int index = handle - (uae_u32) 0x80000000;
+    //printf("check library index %u\n", index);
+    if (index < 0 || index > g_max_handle) {
+        //printf("index < 0 || index > g_max_handle\n");
+        return NULL;
+    }
+    if (g_handles[index].function) {
+        //printf("- g_handles[index].function\n");
+        return NULL;
+    }
+    return g_handles[index].library;
+}
+
+static uae_u32 get_function_handle (uae_u32 handle, const char *name)
+{
+    struct library_data *library_data = get_library_data_from_handle (handle);
+    if (library_data == NULL) {
+        write_log(_T("uni: get_function - invalid library (%d)\n"), handle);
+        return UNI_ERROR_INVALID_LIBRARY;
+    }
+
+    void *function_address = dl_symbol (library_data->dl_handle, name);
+    if (!function_address) {
+        write_log(_T("uni: get_function - function (%s) not found ")
+                _T("in library %d (%p)\n"), name, handle,
+                library_data->dl_handle);
+        return UNI_ERROR_FUNCTION_NOT_FOUND;
+    }
+    return register_handle (library_data, function_address);
+}
+
+uae_u32 uaenative_get_function (TrapContext *context, int flags)
+{
+    if (!currprefs.native_code) {
+        return UNI_ERROR_NOT_ENABLED;
+    }
+
+    //m68k_dreg (regs, 1), m68k_areg (regs, 0),
+    //m68k_dreg (regs, 0), m68k_areg (regs, 1),
+
+    uaecptr name;
+    uae_u32 library;
+    if (flags & UNI_FLAG_COMPAT) {
+        name = m68k_areg (regs, 0);
+        library = m68k_dreg (regs, 1);
+    }
+    else {
+        library = m68k_areg (regs, 0);
+        name = m68k_areg (regs, 1);
+    }
+
+    uae_u32 result = get_function_handle (
+        library, (const char *) get_real_address (name));
+
+    if ((flags & UNI_FLAG_COMPAT) && !(result & 0x80000000)) {
+        // error getting function, return 0 for error in compatibility mode
+        return 0;
+    }
+    return result;
+}
+
+#if defined(X86_MSVC_ASSEMBLY)
+
+static uae_u32 do_call_function_compat_asm (struct uni *uni)
+{
+    unsigned int espstore;
+    void *native_func = uni->native_function;
+    uae_u32 d1 = uni->d1;
+    uae_u32 d2 = uni->d2;
+    uae_u32 d3 = uni->d3;
+    uae_u32 d4 = uni->d4;
+    uae_u32 d5 = uni->d5;
+    uae_u32 d6 = uni->d6;
+    uae_u32 d7 = uni->d7;
+    uae_u32 a1 = uni->a1;
+    uae_u32 a2 = uni->a2;
+    uae_u32 a3 = uni->a3;
+    uae_u32 a4 = uni->a4;
+    uae_u32 a5 = uni->a5;
+    uae_u32 a7 = uni->a7;
+    uae_u32 regs_ = (uae_u32)&regs;
+    void *a6 = uni->uaevar_compat;
+
+    __asm
+    {   mov espstore,esp
+        push regs_
+        push a7
+        push a6
+        push a5
+        push a4
+        push a3
+        push a2
+        push a1
+        push d7
+        push d6
+        push d5
+        push d4
+        push d3
+        push d2
+        push d1
+        call native_func
+        mov esp,espstore
+    }
+}
+
+#endif
+
+static void do_call_function (struct uni *uni) {
+    printf("uni: calling native function %p\n", uni->native_function);
+
+    unsigned long start_time;
+    const int flags = uni->flags;
+    if ((flags & UNI_FLAG_ASYNCHRONOUS) == 0) {
+        start_time = read_processor_time ();
+    }
+
+    if (uni->flags & UNI_FLAG_COMPAT) {
+#if defined(X86_MSVC_ASSEMBLY)
+        uni->result = (uae_s32) do_call_function_compat_asm(uni);
+#else
+        uni->result = ((uae_uni_native_compat_function) uni->native_function) (
+                uni->d1, uni->d2, uni->d3, uni->d4, uni->d5, uni->d6,
+                uni->d7, uni->a1, uni->a2, uni->a3, uni->a4, uni->a5,
+                uni->uaevar_compat, uni->a7, &regs);
+#endif
+    }
+    else {
+        uni->result = ((uae_uni_native_function) uni->native_function) (uni);
+    }
+
+    if ((flags & UNI_FLAG_ASYNCHRONOUS) == 0) {
+        unsigned long time_diff = read_processor_time () - start_time;
+        double v = syncdivisor * time_diff;
+        if (v > 0) {
+            if (v > 1000000 * CYCLE_UNIT) {
+                v = 1000000 * CYCLE_UNIT;
+            }
+            // compensate for the time spent in the native function
+            do_extra_cycles ((unsigned long) (syncdivisor * time_diff));
+        }
+    }
+}
+
+static void *uaenative_thread(void *arg)
+{
+    struct library_data *library_data = (struct library_data *) arg;
+
+    while (1) {
+        uae_sem_wait(&library_data->full_count);
+        if (library_data->thread_stop_flag) {
+            break;
+        }
+        if (library_data->uni) {
+            do_call_function (library_data->uni);
+            uae_Signal (library_data->uni->task, 1 << SIGBIT);
+        }
+        library_data->uni = NULL;
+        uae_sem_post(&library_data->empty_count);
+    }
+
+    write_log (_T("uni: uaenative_thread exiting\n"));
+    free_library_data(library_data);
+    return NULL;
+}
+
+uae_u32 uaenative_call_function (TrapContext *context, int flags)
+{
+    if (!currprefs.native_code) {
+        return UNI_ERROR_NOT_ENABLED;
+    }
+
+    struct uni uni;
+    uni.function = m68k_areg (regs, 0);
+    if (flags & UNI_FLAG_COMPAT) {
+        uni.library = 0;
+        uni.uaevar_compat = uaenative_get_uaevar();
+    }
+    else if (flags & UNI_FLAG_NAMED_FUNCTION) {
+        uni.library = m68k_dreg (regs, 0);
+    }
+    else {
+        uni.library = 0;
+    }
+
+    struct library_data *library_data;
+
+    if (uni.library) {
+        // library handle given, function is pointer to function name
+        const char *function = (const char *) get_real_address (uni.function);
+
+        library_data = get_library_data_from_handle (uni.library);
+        if (library_data == NULL) {
+            write_log (_T("uni: get_function - invalid library (%d)\n"),
+                    uni.library);
+            return UNI_ERROR_INVALID_LIBRARY;
+        }
+
+        uni.native_function = dl_symbol (library_data->dl_handle, function);
+        if (uni.native_function == NULL) {
+            write_log (_T("uni: get_function - function (%s) not found ")
+                       _T("in library %d (%p)\n"), function, uni.library,
+                                                   library_data->dl_handle);
+            return UNI_ERROR_FUNCTION_NOT_FOUND;
+        }
+    }
+    else {
+        // library handle not given, function argument is function handle
+        int index = uni.function - (uae_u32) 0x80000000;
+        if (index >= 0 && index <= g_max_handle) {
+            uni.native_function = g_handles[index].function;
+            library_data = g_handles[index].library;
+        }
+        else {
+            uni.native_function = NULL;
+        }
+        if (uni.native_function == NULL) {
+            // printf ("UNI_ERROR_INVALID_FUNCTION\n");
+            return UNI_ERROR_INVALID_FUNCTION;
+        }
+    }
+
+    if (context == NULL) {
+        // we have no context and cannot call into m68k space
+        flags &= ~UNI_FLAG_ASYNCHRONOUS;
+    }
+
+    uni.d1 = m68k_dreg (regs, 1);
+    uni.d2 = m68k_dreg (regs, 2);
+    uni.d3 = m68k_dreg (regs, 3);
+    uni.d4 = m68k_dreg (regs, 4);
+    uni.d5 = m68k_dreg (regs, 5);
+    uni.d6 = m68k_dreg (regs, 6);
+    uni.d7 = m68k_dreg (regs, 7);
+    uni.a1 = m68k_areg (regs, 1);
+    uni.a2 = m68k_areg (regs, 2);
+    uni.a3 = m68k_areg (regs, 3);
+    uni.a4 = m68k_areg (regs, 4);
+    uni.a5 = m68k_areg (regs, 5);
+    uni.a7 = m68k_areg (regs, 7);
+
+    uni.flags = flags;
+    uni.error = 0;
+
+    if (flags & UNI_FLAG_ASYNCHRONOUS) {
+        uaecptr sysbase = get_long (4);
+        uni.task = get_long (sysbase + 276); // ThisTask
+
+        // make sure signal bit is cleared
+        m68k_dreg (regs, 0) = 0;
+        m68k_dreg (regs, 1) = 1 << SIGBIT;
+        CallLib (context, sysbase, -0x132); // SetSignal
+
+        // start thread if necessary
+        if (!library_data->thread_id) {
+            uae_sem_init (&library_data->full_count, 0, 0);
+            // we don't have a queue as such, the thread only processes
+            // one item at a time with a "queue size" of 1
+            uae_sem_init (&library_data->empty_count, 0, 1);
+            uae_start_thread (_T("uaenative"), uaenative_thread,
+                              library_data, &library_data->thread_id);
+        }
+
+        // signal async thread to process new function call
+        uae_sem_wait(&library_data->empty_count);
+        library_data->uni = &uni;
+        uae_sem_post(&library_data->full_count);
+
+        // wait for signal
+        m68k_dreg (regs, 0) = 1 << SIGBIT;
+        CallLib (context, sysbase, -0x13e); // Wait
+        write_log (_T("uni: -- Got async result --\n"));
+    }
+    else {
+        // synchronous mode, just call the function here and now
+        do_call_function(&uni);
+    }
+    return uni.result;
+}
+
+uae_u32 uaenative_close_library(TrapContext *context, int flags)
+{
+    if (!currprefs.native_code) {
+        return UNI_ERROR_NOT_ENABLED;
+    }
+
+    uae_u32 handle;
+    if (flags & UNI_FLAG_COMPAT) {
+        handle = m68k_dreg (regs, 1);
+    }
+    else {
+        handle = m68k_areg (regs, 1);
+    }
+
+    struct library_data *library_data = get_library_data_from_handle (handle);
+    if (library_data == NULL) {
+        return UNI_ERROR_INVALID_LIBRARY;
+    }
+
+    dl_close (library_data->dl_handle);
+
+    // We now "free" the library and function entries for this library. This
+    // makes the entries available for re-use. The bad thing about this is
+    // that it could be possible for a buggy Amiga program to call a
+    // mismatching function if a function handle is kept after the library
+    // is closed.
+    for (int i = 0; i <= g_max_handle; i++) {
+        if (g_handles[i].library == library_data) {
+            g_handles[i].library = NULL;
+            g_handles[i].function = NULL;
+        }
+    }
+
+    if (library_data->thread_id) {
+        write_log (_T("uni: signalling uaenative_thread to stop\n"));
+        library_data->thread_stop_flag = 1;
+        // wake up thread so it can shut down
+        uae_sem_post(&library_data->full_count);
+    }
+    else {
+        free_library_data(library_data);
+    }
+
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+typedef uae_u32 (REGPARAM2 *uae_library_trap) (TrapContext *context);
+
+struct uae_library_trap_def {
+    uae_library_trap function; // native function pointer for trap
+    int flags;                 // trap flags, e.g. TRAPFLAG_EXTRA_STACK
+    uaecptr aptr;              // address of trap (Amiga-side)
+};
+
+struct uae_library {
+    // these members must be specified
+    const TCHAR *name;
+    const TCHAR *id;
+    int version;
+    int revision;
+    uae_library_trap_def *traps;
+
+    // these members can default to 0
+    int data_size;
+
+    // these members will be initialized by library functions
+    uaecptr aptr_name;
+    uaecptr aptr_id;
+    uaecptr aptr_init;
+    uaecptr aptr_func_table;
+    uaecptr aptr_data_table;
+};
+
+void uae_library_install (struct uae_library *library)
+{
+       library->aptr_name = ds (library->name);
+       library->aptr_id = ds (library->id);
+
+    for (uae_library_trap_def *t = library->traps; t->function; t++) {
+        t->aptr = here ();
+        calltrap (deftrap2 (t->function, t->flags, _T("")));
+        dw (RTS);
+    }
+
+       library->aptr_func_table = here ();
+    for (uae_library_trap_def *t = library->traps + 1; t->function; t++) {
+        dl (t->aptr);
+    }
+       dl (0xFFFFFFFF); // end of table
+
+       library->aptr_data_table = here ();
+       dw (0xE000);     // INITBYTE
+       dw (0x0008);     // LN_TYPE
+       dw (0x0900);     // NT_LIBRARY
+       dw (0xE000);     // INITBYTE
+       dw (0x0009);     // LN_PRI
+       dw (0xCE00);     // -50
+       dw (0xC000);     // INITLONG
+       dw (0x000A);     // LN_NAME
+       dl (library->aptr_name);
+       dw (0xE000);     // INITBYTE
+       dw (0x000E);     // LIB_FLAGS
+       dw (0x0600);     // LIBF_SUMUSED | LIBF_CHANGED
+       dw (0xD000);     // INITWORD
+       dw (0x0014);     // LIB_VERSION
+       dw (library->version);
+       dw (0xD000);
+       dw (0x0016);     // LIB_REVISION
+       dw (library->revision);
+       dw (0xC000);
+       dw (0x0018);     // LIB_IDSTRING
+       dl (library->aptr_id);
+       dl (0x00000000); // end of table
+
+       library->aptr_init = here ();
+       dl (SIZEOF_LIBRARY + library->data_size);
+       dl (library->aptr_func_table);
+       dl (library->aptr_data_table);
+       dl (library->traps[0].aptr);
+
+    write_log (_T("%s installed\n"), library->name);
+}
+
+uaecptr uae_library_startup (uaecptr res_addr, struct uae_library *library)
+{
+       if (library->aptr_name == 0 || !currprefs.native_code) {
+               return res_addr;
+    }
+
+       put_word (res_addr + 0x00, 0x4AFC);
+       put_long (res_addr + 0x02, res_addr);
+       put_long (res_addr + 0x06, res_addr + 0x1A); // Continue scan here
+       put_word (res_addr + 0x0A, 0x8004);          // RTF_AUTOINIT, RT_VERSION
+       put_word (res_addr + 0x0C, 0x0970);          // NT_LIBRARY, RT_PRI
+       put_long (res_addr + 0x0E, library->aptr_name);
+       put_long (res_addr + 0x12, library->aptr_id);
+       put_long (res_addr + 0x16, library->aptr_init);
+
+       return res_addr + 0x1A;
+}
+
+// ----------------------------------------------------------------------------
+
+static uae_u32 REGPARAM2 lib_init (TrapContext *context)
+{
+       uaecptr aptr_base = m68k_dreg (regs, 0);
+#if 0
+       uaecptr aptr_data = aptr_base + SIZEOF_LIBRARY; // sizeof(Library)
+       // our library data area, LIB_DATA_SIZE must be at least as big
+       put_long (aptr_data + 0, somedata);
+#endif
+       return aptr_base;
+}
+
+static uae_u32 REGPARAM2 lib_open (TrapContext *context)
+{
+       // we could do some security checks here if only some specific Amiga
+       // tasks can call us or something like that
+       put_word (m68k_areg (regs, 6) + 32,
+                 get_word (m68k_areg (regs, 6) + 32) + 1);
+       return m68k_areg (regs, 6);
+}
+
+static uae_u32 REGPARAM2 lib_close (TrapContext *context)
+{
+       put_word (m68k_areg (regs, 6) + 32,
+                 get_word (m68k_areg (regs, 6) + 32) - 1);
+       return 0;
+}
+
+static uae_u32 REGPARAM2 lib_expunge (TrapContext *context)
+{
+        return 0;
+}
+
+static uae_u32 REGPARAM2 lib_null (TrapContext *context)
+{
+        return 0;
+}
+
+static uae_u32 REGPARAM2 lib_open_library (TrapContext *context)
+{
+    return uaenative_open_library (context, 0);
+}
+
+static uae_u32 REGPARAM2 lib_close_library (TrapContext *context)
+{
+    return uaenative_close_library (context, 0);
+}
+
+static uae_u32 REGPARAM2 lib_get_function (TrapContext *context)
+{
+    return uaenative_get_function (context, 0);
+}
+
+static uae_u32 REGPARAM2 lib_call_function (TrapContext *context)
+{
+    int flags = 0;
+    return uaenative_call_function (context, flags);
+}
+
+static uae_u32 REGPARAM2 lib_call_function_async (TrapContext *context)
+{
+    int flags = UNI_FLAG_ASYNCHRONOUS;
+    return uaenative_call_function (context, flags);
+}
+
+static uae_u32 REGPARAM2 lib_call_function_by_name (TrapContext *context)
+{
+    int flags = UNI_FLAG_NAMED_FUNCTION;
+    return uaenative_call_function (context, flags);
+}
+
+static uae_u32 REGPARAM2 lib_call_function_by_name_async (TrapContext *context)
+{
+    int flags = UNI_FLAG_ASYNCHRONOUS | UNI_FLAG_NAMED_FUNCTION;
+    return uaenative_call_function (context, flags);
+}
+
+static uae_library_trap_def uaenative_functions[] = {
+    { lib_init },
+    { lib_open },
+    { lib_close },
+    { lib_expunge },
+    { lib_null },
+    { lib_open_library },
+    { lib_close_library },
+    { lib_get_function },
+    { lib_call_function },
+    { lib_call_function_async, TRAPFLAG_EXTRA_STACK },
+    { lib_call_function_by_name },
+    { lib_call_function_by_name_async, TRAPFLAG_EXTRA_STACK },
+    { NULL },
+};
+
+static struct uae_library uaenative_library = {
+    _T("uaenative.library"),
+    _T("UAE Native Interface 1.0"),
+    1, // version
+    0, // revision
+    uaenative_functions,
+};
+
+void uaenative_install (void)
+{
+    uae_library_install (&uaenative_library);
+}
+
+uaecptr uaenative_startup (uaecptr res_addr)
+{
+    return uae_library_startup (res_addr, &uaenative_library);
+}
+
+#endif // WITH_UAENATIVE
index 45c1ed9419b404567788b576b8e9cbbb40127c88..52a50738baa57900a8bbe593cd1cd3dca290af70 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -1023,7 +1023,7 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
                if (!memcmp (buf, "PKD\x13", 4) || !memcmp (buf, "PKD\x11", 4)) {
                        TCHAR *fn;
                        int sectors = buf[18];
-                       int heads = buf[15];
+                       int reserved = buf[15];
                        int blocks = (buf[6] << 8) | buf[7];
                        int blocksize = (buf[10] << 8) | buf[11];
                        struct zfile *zo;
@@ -1034,7 +1034,7 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
                        uae_u8 *nullsector;
 
                        nullsector = xcalloc (uae_u8, blocksize);
-                       sectors /= heads;
+                       sectors /= 2;
                        if (buf[3] == 0x13) {
                                off = 52;
                                if (buf[off - 1] == 1) {
@@ -1047,7 +1047,8 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
                                off = 32;
                        }
 
-                       if (size < 1760 * 512)
+                       // some Amiga disk images are smaller than full adf for some reason
+                       if (sectors == 11 && size < 1760 * 512)
                                size = 1760 * 512;
 
                        if (zfile_getfilename (zi) && _tcslen (zfile_getfilename (zi))) {