]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc0827b4.zip
authorToni Wilen <twilen@winuae.net>
Thu, 3 Jun 2004 15:13:23 +0000 (18:13 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:23:02 +0000 (21:23 +0200)
16 files changed:
blitter.c
custom.c
custom2.c [deleted file]
debug.c
drawing.c
fdi2raw2.c [deleted file]
fdi2raw_old.c [deleted file]
identify.c
include/identify.h
memory.c
od-win32/avioutput.c
od-win32/drivesound.c [deleted file]
od-win32/resources/winuae.rc
od-win32/sounddep/sound.c
od-win32/win32.h
od-win32/win32gui.c

index e36dbf20e1eef99074ca531e6ac04201a39463f3..cfd3b592f3e65c4d714d8fbadff536922f6f6237 100755 (executable)
--- a/blitter.c
+++ b/blitter.c
@@ -30,7 +30,6 @@ uae_u32 bltapt,bltbpt,bltcpt,bltdpt;
 
 int blinea_shift;
 static uae_u16 blinea, blineb;
-static uaecptr bltcnxlpt,bltdnxlpt;
 static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc;
 static int blitonedot,blitsign;
 static int blit_add;
@@ -394,7 +393,7 @@ STATIC_INLINE void blitter_line_incx(void)
 {
     if (++blinea_shift == 16) {
        blinea_shift = 0;
-       bltcnxlpt += 2;
+       bltcpt += 2;
     }
 }
 
@@ -402,19 +401,19 @@ STATIC_INLINE void blitter_line_decx(void)
 {
     if (blinea_shift-- == 0) {
        blinea_shift = 15;
-       bltcnxlpt -= 2;
+       bltcpt -= 2;
     }
 }
 
 STATIC_INLINE void blitter_line_decy(void)
 {
-    bltcnxlpt -= blt_info.bltcmod;
+    bltcpt -= blt_info.bltcmod;
     blitonedot = 0;
 }
 
 STATIC_INLINE void blitter_line_incy(void)
 {
-    bltcnxlpt += blt_info.bltcmod;
+    bltcpt += blt_info.bltcmod;
     blitonedot = 0;
 }
 
@@ -464,7 +463,6 @@ static void blitter_line(void)
 
 STATIC_INLINE void blitter_nxline(void)
 {
-    bltdpt = bltcpt = bltcnxlpt;
     blineb = (blineb << 1) | (blineb >> 15);
     if (--blt_info.vblitsize == 0) {
        bltstate = BLT_done;
@@ -881,8 +879,6 @@ void do_blitter (int hpos)
     reset_blit (1|2); 
 
     if (blitline) {
-       bltcnxlpt = bltcpt;
-       bltdnxlpt = bltdpt;
        blitsing = bltcon1 & 0x2;
        blinea = blt_info.bltadat;
        blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift));
index a1febcc0ea73a1fdf514147cb7886117f3d77c30..059e69d51f710e0abab693a8d85888914fe55214 100755 (executable)
--- a/custom.c
+++ b/custom.c
@@ -194,7 +194,7 @@ static struct color_entry current_colors;
 static unsigned int bplcon0, bplcon1, bplcon2, bplcon3, bplcon4;
 static unsigned int diwstrt, diwstop, diwhigh;
 static int diwhigh_written;
-static unsigned int ddfstrt, ddfstop, ddfstrt_old, ddfstrt_old_hpos, ddfstrt_old_vpos;
+static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos;
 static int ddf_change;
 static unsigned int bplcon0_at_start;
 
@@ -1569,7 +1569,7 @@ STATIC_INLINE void decide_line (int hpos)
            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 (ddfstrt_old != ddfstrt && hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos)
+           if (hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos)
                ok = 0;
            if (ok) {
                start_bpl_dma (hpos, plfstrt);
@@ -1624,6 +1624,7 @@ static void record_color_change (int hpos, int regno, unsigned long value)
 
 typedef int sprbuf_res_t, cclockres_t, hwres_t, bplres_t;
 
+/* handle very rarely needed playfield collision (CLXDAT bit 0) */
 static void do_playfield_collisions (void)
 {
     int bplres = GET_RES (bplcon0);
@@ -2823,11 +2824,10 @@ static void DDFSTRT (int hpos, uae_u16 v)
     v &= 0xfe;
     if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
        v &= 0xfc;
-    if (ddfstrt == v)
+    if (ddfstrt == v && hpos != plfstrt - 2)
        return;
     ddf_change = vpos;
     decide_line (hpos);
-    ddfstrt_old = ddfstrt;
     ddfstrt_old_hpos = hpos;
     ddfstrt_old_vpos = vpos;
     ddfstrt = v;
@@ -3540,7 +3540,7 @@ static void update_copper (int until_hpos)
            cop_state.state = COP_skip_in2;
            break;
         case COP_strobe_delay:
-           cop_state.state = COP_read1;
+           cop_state.state = COP_read1_in2;
            break;
 
        default:
diff --git a/custom2.c b/custom2.c
deleted file mode 100755 (executable)
index 7d7a8b7..0000000
--- a/custom2.c
+++ /dev/null
@@ -1,5527 +0,0 @@
- /*
-  * UAE - The Un*x Amiga Emulator
-  *
-  * Custom chip emulation
-  *
-  * Copyright 1995-2002 Bernd Schmidt
-  * Copyright 1995 Alessandro Bissacco
-  * Copyright 2000-2004 Toni Wilen
-  */
-
-//#define CUSTOM_DEBUG
-#define DEBUG_COPPER 0
-#define SPRITE_DEBUG 0
-#define SPRITE_DEBUG_MINY 0
-#define SPRITE_DEBUG_MAXY 400
-//#define DISABLE_SPRITES
-#define SPR0_HPOS 0x15
-#define MAX_SPRITES 8
-#define SPRITE_COLLISIONS
-#define SPEEDUP
-
-#include "sysconfig.h"
-#include "sysdeps.h"
-
-#include <ctype.h>
-#include <assert.h>
-
-#include "config.h"
-#include "options.h"
-#include "threaddep/thread.h"
-#include "uae.h"
-#include "gensound.h"
-#include "sounddep/sound.h"
-#include "events.h"
-#include "memory.h"
-#include "custom.h"
-#include "newcpu.h"
-#include "cia.h"
-#include "disk.h"
-#include "blitter.h"
-#include "xwin.h"
-#include "inputdevice.h"
-#include "audio.h"
-#include "keybuf.h"
-#include "serial.h"
-#include "osemu.h"
-#include "autoconf.h"
-#include "gui.h"
-#include "picasso96.h"
-#include "drawing.h"
-#include "savestate.h"
-#include "ar.h"
-#include "avioutput.h"
-#include "debug.h"
-#include "akiko.h"
-#include "enforcer.h"
-
-void uae_abort (const char *format,...)
-{
-    va_list parms;
-    char buffer[1000];
-
-    va_start (parms, format);
-    _vsnprintf( buffer, sizeof (buffer) -1, format, parms );
-    va_end (parms);
-    gui_message (buffer);
-    activate_debugger ();
-}
-
-#if 0
-void customhack_put (struct customhack *ch, uae_u16 v, int hpos)
-{
-    ch->v = v;
-    ch->vpos = vpos;
-    ch->hpos = hpos;
-}
-
-uae_u16 customhack_get (struct customhack *ch, int hpos)
-{
-    if (ch->vpos == vpos && ch->hpos == hpos) {
-       ch->vpos = -1;
-       return 0xffff;
-    }
-    return ch->v;
-}
-#endif
-
-static uae_u16 last_custom_value;
-
-static unsigned int n_consecutive_skipped = 0;
-static unsigned int total_skipped = 0;
-
-STATIC_INLINE void sync_copper (int hpos);
-
-/* Events */
-unsigned long int event_cycles, nextevent, is_lastline, currcycle;
-long cycles_to_next_event;
-long max_cycles_to_next_event;
-long cycles_to_hsync_event;
-
-static int rpt_did_reset;
-struct ev eventtab[ev_max];
-
-volatile frame_time_t vsynctime, vsyncmintime;
-
-int ievent_alive = 0;
-#ifdef JIT
-extern uae_u8* compiled_code;
-#endif
-
-int vpos;
-int hack_vpos;
-static uae_u16 lof;
-static int next_lineno;
-static enum nln_how nextline_how;
-static int lof_changed = 0;
-
-static uae_u32 sprtaba[256],sprtabb[256];
-static uae_u32 sprite_ab_merge[256];
-/* Tables for collision detection.  */
-static uae_u32 sprclx[16], clxmask[16];
-
-/*
- * Hardware registers of all sorts.
- */
-
-static int custom_wput_1 (int, uaecptr, uae_u32, int) REGPARAM;
-
-static uae_u16 cregs[256];
-
-uae_u16 intena,intreq;
-uae_u16 dmacon;
-uae_u16 adkcon; /* used by audio code */
-
-static uae_u32 cop1lc,cop2lc,copcon;
-int maxhpos = MAXHPOS_PAL;
-int maxvpos = MAXVPOS_PAL;
-int minfirstline = VBLANK_ENDLINE_PAL;
-int vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_skip;
-unsigned long syncbase;
-static int fmode;
-unsigned int beamcon0, new_beamcon0;
-uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL;
-static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter;
-
-#define HSYNCTIME (maxhpos * CYCLE_UNIT);
-
-/* This is but an educated guess. It seems to be correct, but this stuff
- * isn't documented well. */
-struct sprite {
-    uaecptr pt;
-    int xpos;
-    int vstart;
-    int vstop;
-    int armed;
-    int dmastate;
-    int dmacycle;
-};
-
-static struct sprite spr[MAX_SPRITES];
-
-static int sprite_vblank_endline = VBLANK_SPRITE_PAL;
-
-static unsigned int sprctl[MAX_SPRITES], sprpos[MAX_SPRITES];
-#ifdef AGA
-static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4];
-#else
-static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1];
-#endif
-static int sprite_last_drawn_at[MAX_SPRITES];
-static int last_sprite_point, nr_armed;
-static int sprite_width, sprres, sprite_buffer_res;
-
-#ifdef CPUEMU_6
-uae_u8 cycle_line[256];
-#endif
-
-static uae_u32 bpl1dat, bpl2dat, bpl3dat, bpl4dat, bpl5dat, bpl6dat, bpl7dat, bpl8dat;
-static uae_s16 bpl1mod, bpl2mod;
-
-static uaecptr bplpt[8];
-uae_u8 *real_bplpt[8];
-/* Used as a debugging aid, to offset any bitplane temporarily.  */
-int bpl_off[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/*static int blitcount[256];  blitter debug */
-
-static struct color_entry current_colors;
-static unsigned int bplcon0, bplcon1, bplcon2, bplcon3, bplcon4;
-static unsigned int diwstrt, diwstop, diwhigh;
-static int diwhigh_written;
-static unsigned int ddfstrt, ddfstop, ddfstrt_old, ddfstrt_old_hpos, ddfstrt_old_vpos;
-static int ddf_change;
-static unsigned int bplcon0_at_start;
-
-/* The display and data fetch windows */
-
-enum diw_states
-{
-    DIW_waiting_start, DIW_waiting_stop
-};
-
-int plffirstline, plflastline;
-int plfstrt, plfstop;
-static int last_diw_pix_hpos, last_ddf_pix_hpos, last_decide_line_hpos;
-static int last_fetch_hpos, last_sprite_hpos;
-int diwfirstword, diwlastword;
-static enum diw_states diwstate, hdiwstate, ddfstate;
-
-/* Sprite collisions */
-static unsigned int clxdat, clxcon, clxcon2, clxcon_bpl_enable, clxcon_bpl_match;
-
-enum copper_states {
-    COP_stop,
-    COP_read1_in2,
-    COP_read1_wr_in4,
-    COP_read1_wr_in2,
-    COP_read1,
-    COP_read2_wr_in2,
-    COP_read2,
-    COP_bltwait,
-    COP_wait_in4,
-    COP_wait_in2,
-    COP_skip_in4,
-    COP_skip_in2,
-    COP_wait1,
-    COP_wait,
-    COP_skip1,
-    COP_strobe_delay
-};
-
-struct copper {
-    /* The current instruction words.  */
-    unsigned int i1, i2;
-    unsigned int saved_i1, saved_i2;
-    enum copper_states state;
-    /* Instruction pointer.  */
-    uaecptr ip, saved_ip;
-    int hpos, vpos;
-    unsigned int ignore_next;
-    int vcmp, hcmp;
-
-    /* When we schedule a copper event, knowing a few things about the future
-       of the copper list can reduce the number of sync_with_cpu calls
-       dramatically.  */
-    unsigned int first_sync;
-    unsigned int regtypes_modified;
-    int strobe; /* COPJMP1 / COPJMP2 accessed */
-};
-
-#define REGTYPE_NONE 0
-#define REGTYPE_COLOR 1
-#define REGTYPE_SPRITE 2
-#define REGTYPE_PLANE 4
-#define REGTYPE_BLITTER 8
-#define REGTYPE_JOYPORT 16
-#define REGTYPE_DISK 32
-#define REGTYPE_POS 64
-#define REGTYPE_AUDIO 128
-
-#define REGTYPE_ALL 255
-/* Always set in regtypes_modified, to enable a forced update when things like
-   DMACON, BPLCON0, COPJMPx get written.  */
-#define REGTYPE_FORCE 256
-
-
-static unsigned int regtypes[512];
-
-static struct copper cop_state;
-static int copper_enabled_thisline;
-static int cop_min_waittime;
-
-/*
- * Statistics
- */
-
-/* Used also by bebox.cpp */
-unsigned long int frametime = 0, lastframetime = 0, timeframes = 0, hsync_counter = 0;
-unsigned long int idletime;
-int bogusframe;
-
-#if DEBUG_COPPER
-/* 10000 isn't enough!  */
-#define NR_COPPER_RECORDS 40000
-#else
-#define NR_COPPER_RECORDS 1
-#endif
-
-/* Record copper activity for the debugger.  */
-struct cop_record
-{
-  int hpos, vpos;
-  uaecptr addr;
-};
-static struct cop_record cop_record[2][NR_COPPER_RECORDS];
-static int nr_cop_records[2];
-static int curr_cop_set;
-
-/* Recording of custom chip register changes.  */
-static int current_change_set;
-
-#ifdef OS_WITHOUT_MEMORY_MANAGEMENT
-/* sam: Those arrays uses around 7Mb of BSS... That seems  */
-/* too much for AmigaDOS (uae crashes as soon as one loads */
-/* it. So I use a different strategy here (realloc the     */
-/* arrays when needed. That strategy might be usefull for  */
-/* computer with low memory.                               */
-struct sprite_entry  *sprite_entries[2];
-struct color_change *color_changes[2];
-static int max_sprite_entry = 400;
-static int delta_sprite_entry = 0;
-static int max_color_change = 400;
-static int delta_color_change = 0;
-#else
-struct sprite_entry sprite_entries[2][MAX_SPR_PIXELS / 16];
-struct color_change color_changes[2][MAX_REG_CHANGE];
-#endif
-
-struct decision line_decisions[2 * (MAXVPOS + 1) + 1];
-struct draw_info line_drawinfo[2][2 * (MAXVPOS + 1) + 1];
-struct color_entry color_tables[2][(MAXVPOS + 1) * 2];
-
-static int next_sprite_entry = 0;
-static int prev_next_sprite_entry;
-static int next_sprite_forced = 1;
-
-struct sprite_entry *curr_sprite_entries, *prev_sprite_entries;
-struct color_change *curr_color_changes, *prev_color_changes;
-struct draw_info *curr_drawinfo, *prev_drawinfo;
-struct color_entry *curr_color_tables, *prev_color_tables;
-
-static int next_color_change;
-static int next_color_entry, remembered_color_entry;
-static int color_src_match, color_dest_match, color_compare_result;
-
-static uae_u32 thisline_changed;
-
-#ifdef SMART_UPDATE
-#define MARK_LINE_CHANGED do { thisline_changed = 1; } while (0)
-#else
-#define MARK_LINE_CHANGED do { ; } while (0)
-#endif
-
-static struct decision thisline_decision;
-static int passed_plfstop, fetch_cycle;
-
-enum fetchstate {
-    fetch_not_started,
-    fetch_started,
-    fetch_was_plane0
-} fetch_state;
-
-/*
- * helper functions
- */
-
-uae_u32 get_copper_address (int copno)
-{
-    switch (copno) {
-    case 1: return cop1lc;
-    case 2: return cop2lc;
-    default: return 0;
-    }
-}
-
-STATIC_INLINE void record_copper (uaecptr addr, int hpos, int vpos)
-{
-#if DEBUG_COPPER
-    int t = nr_cop_records[curr_cop_set];
-    if (t < NR_COPPER_RECORDS) {
-       cop_record[curr_cop_set][t].addr = addr;
-       cop_record[curr_cop_set][t].hpos = hpos;
-       cop_record[curr_cop_set][t].vpos = vpos;
-       nr_cop_records[curr_cop_set] = t + 1;
-    }
-#endif
-}
-
-int find_copper_record (uaecptr addr, int *phpos, int *pvpos)
-{
-    int s = curr_cop_set ^ 1;
-    int t = nr_cop_records[s];
-    int i;
-    for (i = 0; i < t; i++) {
-       if (cop_record[s][i].addr == addr) {
-           *phpos = cop_record[s][i].hpos;
-           *pvpos = cop_record[s][i].vpos;
-           return 1;
-       }
-    }
-    return 0;
-}
-
-int rpt_available = 0;
-
-void reset_frame_rate_hack (void)
-{
-    if (currprefs.m68k_speed != -1)
-       return;
-
-    if (! rpt_available) {
-       currprefs.m68k_speed = 0;
-       return;
-    }
-
-    rpt_did_reset = 1;
-    is_lastline = 0;
-    vsyncmintime = read_processor_time() + vsynctime;
-    write_log ("Resetting frame rate hack\n");
-}
-
-STATIC_INLINE void setclr (uae_u16 *p, uae_u16 val)
-{
-    if (val & 0x8000)
-       *p |= val & 0x7FFF;
-    else
-       *p &= ~val;
-}
-
-STATIC_INLINE int current_hpos (void)
-{
-    return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
-}
-
-STATIC_INLINE uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount)
-{
-    if (!chipmem_bank.check (plpt, bytecount)) {
-       static int count = 0;
-       if (!count)
-           count++, write_log ("Warning: Bad playfield pointer\n");
-       return NULL;
-    }
-    return chipmem_bank.xlateaddr (plpt);
-}
-
-STATIC_INLINE void docols (struct color_entry *colentry)
-{
-    int i;
-
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA) {
-       for (i = 0; i < 256; i++) {
-           int v = color_reg_get (colentry, i);
-           if (v < 0 || v > 16777215)
-               continue;
-           colentry->acolors[i] = CONVERT_RGB (v);
-       }
-    } else {
-#endif
-        for (i = 0; i < 32; i++) {
-           int v = color_reg_get (colentry, i);
-           if (v < 0 || v > 4095)
-               continue;
-           colentry->acolors[i] = xcolors[v];
-       }
-#ifdef AGA
-    }
-#endif
-}
-
-void notice_new_xcolors (void)
-{
-    int i;
-
-    docols(&current_colors);
-/*    docols(&colors_for_drawing);*/
-    for (i = 0; i < (MAXVPOS + 1)*2; i++) {
-       docols(color_tables[0]+i);
-       docols(color_tables[1]+i);
-    }
-}
-
-static void do_sprites (int currhp);
-
-static void remember_ctable (void)
-{
-    if (remembered_color_entry == -1) {
-       /* The colors changed since we last recorded a color map. Record a
-        * new one. */
-       color_reg_cpy (curr_color_tables + next_color_entry, &current_colors);
-       remembered_color_entry = next_color_entry++;
-    }
-    thisline_decision.ctable = remembered_color_entry;
-    if (color_src_match == -1 || color_dest_match != remembered_color_entry
-       || line_decisions[next_lineno].ctable != color_src_match)
-    {
-       /* The remembered comparison didn't help us - need to compare again. */
-       int oldctable = line_decisions[next_lineno].ctable;
-       int changed = 0;
-
-       if (oldctable == -1) {
-           changed = 1;
-           color_src_match = color_dest_match = -1;
-       } else {
-           color_compare_result = color_reg_cmp (&prev_color_tables[oldctable], &current_colors) != 0;
-           if (color_compare_result)
-               changed = 1;
-           color_src_match = oldctable;
-           color_dest_match = remembered_color_entry;
-       }
-       thisline_changed |= changed;
-    } else {
-       /* We know the result of the comparison */
-       if (color_compare_result)
-           thisline_changed = 1;
-    }
-}
-
-static void remember_ctable_for_border (void)
-{
-    remember_ctable ();
-}
-
-/* Called to determine the state of the horizontal display window state
- * machine at the current position. It might have changed since we last
- * checked.  */
-static void decide_diw (int hpos)
-{
-    int pix_hpos = coord_diw_to_window_x (hpos == 227 ? 455 : hpos * 2); /* (227.5*2 = 455) */
-    if (hdiwstate == DIW_waiting_start && thisline_decision.diwfirstword == -1
-       && pix_hpos >= diwfirstword && last_diw_pix_hpos < diwfirstword)
-    {
-       thisline_decision.diwfirstword = diwfirstword < 0 ? 0 : diwfirstword;
-       hdiwstate = DIW_waiting_stop;
-    }
-    if (hdiwstate == DIW_waiting_stop && thisline_decision.diwlastword == -1
-       && pix_hpos >= diwlastword && last_diw_pix_hpos < diwlastword)
-    {
-       thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword;
-       hdiwstate = DIW_waiting_start;
-    }
-    last_diw_pix_hpos = pix_hpos;
-}
-
-/* The HRM says 0xD8, but that can't work... */
-#define HARD_DDF_STOP 0xd4
-#define HARD_DDF_START 0x18
-
-static void add_modulos (void)
-{
-    int m1, m2;
-
-    if (fmode & 0x4000) {
-       if (((diwstrt >> 8) ^ vpos) & 1)
-           m1 = m2 = bpl2mod;
-       else
-           m1 = m2 = bpl1mod;
-    } else {
-       m1 = bpl1mod;
-       m2 = bpl2mod;
-    }
-
-    switch (GET_PLANES (bplcon0)) {
-#ifdef AGA
-       case 8: bplpt[7] += m2;
-       case 7: bplpt[6] += m1;
-#endif
-       case 6: bplpt[5] += m2;
-       case 5: bplpt[4] += m1;
-       case 4: bplpt[3] += m2;
-       case 3: bplpt[2] += m1;
-       case 2: bplpt[1] += m2;
-       case 1: bplpt[0] += m1;
-    }
-}
-
-static void finish_playfield_line (void)
-{
-    /* The latter condition might be able to happen in interlaced frames. */
-    if (vpos >= minfirstline && (thisframe_first_drawn_line == -1 || vpos < thisframe_first_drawn_line))
-       thisframe_first_drawn_line = vpos;
-    thisframe_last_drawn_line = vpos;
-
-    /* These are for comparison. */
-    thisline_decision.bplcon0 = bplcon0;
-    thisline_decision.bplcon2 = bplcon2;
-#ifdef AGA
-    thisline_decision.bplcon3 = bplcon3;
-    thisline_decision.bplcon4 = bplcon4;
-#endif
-
-#ifdef SMART_UPDATE
-    if (line_decisions[next_lineno].plflinelen != thisline_decision.plflinelen
-       || line_decisions[next_lineno].plfleft != thisline_decision.plfleft
-       || line_decisions[next_lineno].bplcon0 != thisline_decision.bplcon0
-       || line_decisions[next_lineno].bplcon2 != thisline_decision.bplcon2
-#ifdef AGA
-       || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3
-       || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4
-#endif
-       )
-#endif /* SMART_UPDATE */
-       thisline_changed = 1;
-}
-
-static int fetchmode;
-
-/* The fetch unit mainly controls ddf stop.  It's the number of cycles that
-   are contained in an indivisible block during which ddf is active.  E.g.
-   if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are
-   0x30 + n * 8.  */
-static int fetchunit, fetchunit_mask;
-/* The delay before fetching the same bitplane again.  Can be larger than
-   the number of bitplanes; in that case there are additional empty cycles
-   with no data fetch (this happens for high fetchmodes and low
-   resolutions).  */
-static int fetchstart, fetchstart_shift, fetchstart_mask;
-/* fm_maxplane holds the maximum number of planes possible with the current
-   fetch mode.  This selects the cycle diagram:
-   8 planes: 73516240
-   4 planes: 3120
-   2 planes: 10.  */
-static int fm_maxplane, fm_maxplane_shift;
-
-/* The corresponding values, by fetchmode and display resolution.  */
-static int fetchunits[] = { 8,8,8,0, 16,8,8,0, 32,16,8,0 };
-static int fetchstarts[] = { 3,2,1,0, 4,3,2,0, 5,4,3,0 };
-static int fm_maxplanes[] = { 3,2,1,0, 3,3,2,0, 3,3,3,0 }; 
-
-static uae_u8 cycle_diagram_table[3][3][9][32];
-static uae_u8 cycle_diagram_free_cycles[3][3][9];
-static uae_u8 cycle_diagram_total_cycles[3][3][9];
-static uae_u8 *curr_diagram;
-static uae_u8 cycle_sequences[3*8] = { 2,1,2,1,2,1,2,1, 4,2,3,1,4,2,3,1, 8,4,6,2,7,3,5,1 };
-
-static void debug_cycle_diagram(void)
-{
-    int fm, res, planes, cycle, v;
-    char aa;
-
-    for (fm = 0; fm < 3; fm++) {
-       write_log ("FMODE %d\n=======\n", fm);
-       for (res = 0; res <= 2; res++) {
-           for (planes = 0; planes <= 8; planes++) {
-               write_log("%d: ",planes);
-               for (cycle = 0; cycle < 32; cycle++) {
-                   v=cycle_diagram_table[fm][res][planes][cycle];
-                   if (v==0) aa='-'; else if(v>0) aa='1'; else aa='X';
-                   write_log("%c",aa);
-               }
-               write_log(" %d:%d\n", 
-                   cycle_diagram_free_cycles[fm][res][planes], cycle_diagram_total_cycles[fm][res][planes]);
-           }
-           write_log("\n");
-       }
-    }
-    fm=0;
-}
-
-static void create_cycle_diagram_table(void)
-{
-    int fm, res, cycle, planes, v;
-    int fetch_start, max_planes, freecycles;
-    uae_u8 *cycle_sequence;
-
-    for (fm = 0; fm <= 2; fm++) {
-       for (res = 0; res <= 2; res++) {
-           max_planes = fm_maxplanes[fm * 4 + res];
-           fetch_start = 1 << fetchstarts[fm * 4 + res];
-           cycle_sequence = &cycle_sequences[(max_planes - 1) * 8];
-           max_planes = 1 << max_planes;
-           for (planes = 0; planes <= 8; planes++) {
-               freecycles = 0;
-               for (cycle = 0; cycle < 32; cycle++)
-                   cycle_diagram_table[fm][res][planes][cycle] = -1;
-               if (planes <= max_planes) {
-                   for (cycle = 0; cycle < fetch_start; cycle++) {
-                       if (cycle < max_planes && planes >= cycle_sequence[cycle & 7]) {
-                           v = 1;
-                       } else {
-                           v = 0;
-                           freecycles++;
-                       }
-                       cycle_diagram_table[fm][res][planes][cycle] = v;
-                   }
-               }
-               cycle_diagram_free_cycles[fm][res][planes] = freecycles;
-               cycle_diagram_total_cycles[fm][res][planes] = fetch_start;
-           }
-       }
-    }
-#if 0
-    debug_cycle_diagram ();
-#endif
-}
-
-
-/* Used by the copper.  */
-static int estimated_last_fetch_cycle;
-static int cycle_diagram_shift;
-
-static void estimate_last_fetch_cycle (int hpos)
-{
-    int fetchunit = fetchunits[fetchmode * 4 + GET_RES (bplcon0)];
-
-    if (! passed_plfstop) {
-       int stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop;
-       /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle.  */
-       int fetch_cycle_at_stop = fetch_cycle + (stop - hpos);
-       int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1);
-
-       estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
-    } else {
-       int starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1);
-       if (passed_plfstop == 2)
-           starting_last_block_at -= fetchunit;
-
-       estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
-    }
-}
-
-static uae_u32 outword[MAX_PLANES];
-static int out_nbits, out_offs;
-static uae_u32 todisplay[MAX_PLANES][4];
-static uae_u32 fetched[MAX_PLANES];
-#ifdef AGA
-static uae_u32 fetched_aga0[MAX_PLANES];
-static uae_u32 fetched_aga1[MAX_PLANES];
-#endif
-
-/* Expansions from bplcon0/bplcon1.  */
-static int toscr_res, toscr_res_first, toscr_nr_planes, fetchwidth;
-static int toscr_delay1x, toscr_delay2x, toscr_delay1, toscr_delay2;
-
-/* The number of bits left from the last fetched words.  
-   This is an optimization - conceptually, we have to make sure the result is
-   the same as if toscr is called in each clock cycle.  However, to speed this
-   up, we accumulate display data; this variable keeps track of how much. 
-   Thus, once we do call toscr_nbits (which happens at least every 16 bits),
-   we can do more work at once.  */
-static int toscr_nbits;
-
-static int delayoffset;
-
-STATIC_INLINE void compute_delay_offset (void)
-{
-    delayoffset = ((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1;
-    if (delayoffset & 8)
-       delayoffset = 8;
-    else if (delayoffset & 16)
-       delayoffset = 16;
-    else if (delayoffset & 32)
-       delayoffset = 32;
-    else
-       delayoffset = 0;
-}
-
-static void expand_fmodes (void)
-{
-    int res = GET_RES(bplcon0);
-    int fm = fetchmode;
-    fetchunit = fetchunits[fm * 4 + res];
-    fetchunit_mask = fetchunit - 1;
-    fetchstart_shift = fetchstarts[fm * 4 + res];
-    fetchstart = 1 << fetchstart_shift;
-    fetchstart_mask = fetchstart - 1;
-    fm_maxplane_shift = fm_maxplanes[fm * 4 + res];
-    fm_maxplane = 1 << fm_maxplane_shift;
-    curr_diagram = cycle_diagram_table[fm][res][GET_PLANES (bplcon0)];
-}
-
-static int maxplanes_ocs[]={ 6,4,0,0 };
-static int maxplanes_ecs[]={ 6,4,2,0 };
-static int maxplanes_aga[]={ 8,4,2,0, 8,8,4,0, 8,8,8,0 };
-
-/* Expand bplcon0/bplcon1 into the toscr_xxx variables.  */
-static void compute_toscr_delay_1 (void)
-{
-    int delay1 = (bplcon1 & 0x0f) | ((bplcon1 & 0x0c00) >> 6);
-    int delay2 = ((bplcon1 >> 4) & 0x0f) | (((bplcon1 >> 4) & 0x0c00) >> 6);
-    int delaymask;
-    int fetchwidth = 16 << fetchmode;
-
-    delay1 += delayoffset;
-    delay2 += delayoffset;
-    delaymask = (fetchwidth - 1) >> toscr_res;
-    toscr_delay1x = (delay1 & delaymask) << toscr_res;
-    toscr_delay2x = (delay2 & delaymask) << toscr_res;
-}
-
-static int get_maxplanes (int res)
-{
-    int *planes;
-    if (currprefs.chipset_mask & CSMASK_AGA)
-       planes = maxplanes_aga;
-    else if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE))
-       planes = maxplanes_ocs;
-    else
-       planes = maxplanes_ecs;
-    return planes[fetchmode * 4 + res];
-}
-
-static void compute_toscr_delay (int hpos)
-{
-    int v = bplcon0;
-    /* Disable bitplane DMA if planes > maxplanes.  This is needed e.g. by the
-       Sanity WOC demo (at the "Party Effect").  */
-    if (GET_PLANES(v) > get_maxplanes (GET_RES(v)))
-       v &= ~0x7010;
-    toscr_res = GET_RES (v);
-    toscr_nr_planes = GET_PLANES (v);
-    compute_toscr_delay_1 ();
-}
-
-STATIC_INLINE void maybe_first_bpl1dat (int hpos)
-{
-    if (thisline_decision.plfleft == -1) {
-       thisline_decision.plfleft = hpos;
-       compute_delay_offset ();
-       compute_toscr_delay_1 ();
-    }
-}
-
-STATIC_INLINE void fetch (int nr, int fm)
-{
-    uaecptr p;
-    if (nr >= toscr_nr_planes)
-       return;
-    p = bplpt[nr] + bpl_off[nr];
-    switch (fm) {
-    case 0:
-       fetched[nr] = last_custom_value = chipmem_wget (p);
-       bplpt[nr] += 2;
-       break;
-#ifdef AGA
-    case 1:
-       fetched_aga0[nr] = chipmem_lget (p);
-       last_custom_value = (uae_u16)fetched_aga0[nr];
-       bplpt[nr] += 4;
-       break;
-    case 2:
-       fetched_aga1[nr] = chipmem_lget (p);
-       fetched_aga0[nr] = chipmem_lget (p + 4);
-       last_custom_value = (uae_u16)fetched_aga0[nr];
-       bplpt[nr] += 8;
-       break;
-#endif
-    }
-    if (passed_plfstop == 2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetchunit - fetchstart) {
-       int mod;
-       if (fmode & 0x4000) {
-           if (((diwstrt >> 8) ^ vpos) & 1)
-               mod = bpl2mod;
-           else
-               mod = bpl1mod;
-       } else if (nr & 1)
-           mod = bpl2mod;
-       else
-           mod = bpl1mod;
-       bplpt[nr] += mod;
-    }
-    if (nr == 0)
-       fetch_state = fetch_was_plane0;
-}
-
-static void clear_fetchbuffer (uae_u32 *ptr, int nwords)
-{
-    int i;
-
-    if (! thisline_changed)
-       for (i = 0; i < nwords; i++)
-           if (ptr[i]) {
-               thisline_changed = 1;
-               break;
-           }
-
-    memset (ptr, 0, nwords * 4);
-}
-
-static void update_toscr_planes (void)
-{
-    if (toscr_nr_planes > thisline_decision.nr_planes) {
-       int j;
-       for (j = thisline_decision.nr_planes; j < toscr_nr_planes; j++)
-           clear_fetchbuffer ((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs);
-#if 0
-       if (thisline_decision.nr_planes > 0)
-           printf ("Planes from %d to %d\n", thisline_decision.nr_planes, toscr_nr_planes);
-#endif
-       thisline_decision.nr_planes = toscr_nr_planes;
-    }
-}
-
-STATIC_INLINE void toscr_3_ecs (int nbits)
-{
-    int delay1 = toscr_delay1;
-    int delay2 = toscr_delay2;
-    int i;
-    uae_u32 mask = 0xFFFF >> (16 - nbits);
-
-    for (i = 0; i < toscr_nr_planes; i += 2) {
-       outword[i] <<= nbits;
-       outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask;
-       todisplay[i][0] <<= nbits;
-    }
-    for (i = 1; i < toscr_nr_planes; i += 2) {
-       outword[i] <<= nbits;
-       outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask;
-       todisplay[i][0] <<= nbits;
-    }
-}
-
-STATIC_INLINE void shift32plus (uae_u32 *p, int n)
-{
-    uae_u32 t = p[1];
-    t <<= n;
-    t |= p[0] >> (32 - n);
-    p[1] = t;
-}
-
-#ifdef AGA
-STATIC_INLINE void aga_shift (uae_u32 *p, int n, int fm)
-{
-    if (fm == 2) {
-       shift32plus (p + 2, n);
-       shift32plus (p + 1, n);
-    }
-    shift32plus (p + 0, n);
-    p[0] <<= n;
-}
-
-STATIC_INLINE void toscr_3_aga (int nbits, int fm)
-{
-    int delay1 = toscr_delay1;
-    int delay2 = toscr_delay2;
-    int i;
-    uae_u32 mask = 0xFFFF >> (16 - nbits);
-
-    {
-       int offs = (16 << fm) - nbits + delay1;
-       int off1 = offs >> 5;
-       if (off1 == 3)
-           off1 = 2;
-       offs -= off1 * 32;
-       for (i = 0; i < toscr_nr_planes; i += 2) {
-           uae_u32 t0 = todisplay[i][off1];
-           uae_u32 t1 = todisplay[i][off1 + 1];
-           uae_u64 t = (((uae_u64)t1) << 32) | t0;
-           outword[i] <<= nbits;
-           outword[i] |= (t >> offs) & mask;
-           aga_shift (todisplay[i], nbits, fm);
-       }
-    }
-    {
-       int offs = (16 << fm) - nbits + delay2;
-       int off1 = offs >> 5;
-       if (off1 == 3)
-           off1 = 2;
-       offs -= off1 * 32;
-       for (i = 1; i < toscr_nr_planes; i += 2) {
-           uae_u32 t0 = todisplay[i][off1];
-           uae_u32 t1 = todisplay[i][off1 + 1];
-           uae_u64 t = (((uae_u64)t1) << 32) | t0;
-           outword[i] <<= nbits;
-           outword[i] |= (t >> offs) & mask;
-           aga_shift (todisplay[i], nbits, fm);
-       }
-    }
-}
-
-#endif
-
-static void toscr_2_0 (int nbits) { toscr_3_ecs (nbits); }
-#ifdef AGA
-static void toscr_2_1 (int nbits) { toscr_3_aga (nbits, 1); }
-static void toscr_2_2 (int nbits) { toscr_3_aga (nbits, 2); }
-#endif
-
-STATIC_INLINE void toscr_1 (int nbits, int fm)
-{
-    switch (fm) {
-    case 0:
-       toscr_2_0 (nbits);
-       break;
-#ifdef AGA
-    case 1:
-       toscr_2_1 (nbits);
-       break;
-    case 2:
-       toscr_2_2 (nbits);
-       break;
-#endif
-    }
-    out_nbits += nbits;
-    if (out_nbits == 32) {
-       int i;
-       uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4;
-       for (i = 0; i < thisline_decision.nr_planes; i++) {
-           uae_u32 *dataptr32 = (uae_u32 *)dataptr;
-           if (i >= toscr_nr_planes)
-               outword[i] = 0;
-           if (*dataptr32 != outword[i])
-               thisline_changed = 1;
-           *dataptr32 = outword[i];
-           dataptr += MAX_WORDS_PER_LINE * 2;
-       }
-       out_offs++;
-       out_nbits = 0;
-    }
-}
-
-static void toscr_fm0 (int);
-static void toscr_fm1 (int);
-static void toscr_fm2 (int);
-
-STATIC_INLINE void toscr (int nbits, int fm)
-{
-    switch (fm) {
-    case 0: toscr_fm0 (nbits); break;
-#ifdef AGA
-    case 1: toscr_fm1 (nbits); break;
-    case 2: toscr_fm2 (nbits); break;
-#endif
-    }
-}
-
-STATIC_INLINE void toscr_0 (int nbits, int fm)
-{
-    int t;
-
-    if (nbits > 16) {
-       toscr (16, fm);
-       nbits -= 16;
-    }
-
-    t = 32 - out_nbits;
-    if (t < nbits) {
-       toscr_1 (t, fm);
-       nbits -= t;
-    }
-    toscr_1 (nbits, fm);
-}
-
-static void toscr_fm0 (int nbits) { toscr_0 (nbits, 0); }
-static void toscr_fm1 (int nbits) { toscr_0 (nbits, 1); }
-static void toscr_fm2 (int nbits) { toscr_0 (nbits, 2); }
-
-static int flush_plane_data (int fm)
-{
-    int i = 0;
-    int fetchwidth = 16 << fm;
-
-    if (out_nbits <= 16) {
-       i += 16;
-       toscr_1 (16, fm);
-    }
-    if (out_nbits != 0) {
-       i += 32 - out_nbits;
-       toscr_1 (32 - out_nbits, fm);
-    }
-    i += 32;
-
-    toscr_1 (16, fm);
-    toscr_1 (16, fm);
-    return i >> (1 + toscr_res);
-}
-
-STATIC_INLINE void flush_display (int fm)
-{
-    if (toscr_nbits > 0 && thisline_decision.plfleft != -1)
-       toscr (toscr_nbits, fm);
-    toscr_nbits = 0;
-}
-
-/* Called when all planes have been fetched, i.e. when a new block
-   of data is available to be displayed.  The data in fetched[] is
-   moved into todisplay[].  */
-STATIC_INLINE void beginning_of_plane_block (int pos, int fm)
-{
-    int i;
-
-    flush_display (fm);
-    if (fm == 0)
-       for (i = 0; i < MAX_PLANES; i++)
-           todisplay[i][0] |= fetched[i];
-#ifdef AGA
-    else
-       for (i = 0; i < MAX_PLANES; i++) {
-           if (fm == 2)
-               todisplay[i][1] = fetched_aga1[i];
-           todisplay[i][0] = fetched_aga0[i];
-       }
-#endif
-    maybe_first_bpl1dat (pos);
-    toscr_delay1 = toscr_delay1x;
-    toscr_delay2 = toscr_delay2x;
-}
-
-#ifdef SPEEDUP
-
-/* The usual inlining tricks - don't touch unless you know what you are doing.  */
-STATIC_INLINE void long_fetch_ecs (int plane, int nwords, int weird_number_of_bits, int dma)
-{
-    uae_u16 *real_pt = (uae_u16 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2);
-    int delay = (plane & 1) ? toscr_delay2 : toscr_delay1;
-    int tmp_nbits = out_nbits;
-    uae_u32 shiftbuffer = todisplay[plane][0];
-    uae_u32 outval = outword[plane];
-    uae_u32 fetchval = fetched[plane];
-    uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs);
-
-    if (dma)
-       bplpt[plane] += nwords * 2;
-
-    if (real_pt == 0)
-       /* @@@ Don't do this, fall back on chipmem_wget instead.  */
-       return;
-
-    while (nwords > 0) {
-       int bits_left = 32 - tmp_nbits;
-       uae_u32 t;
-
-       shiftbuffer |= fetchval;
-
-       t = (shiftbuffer >> delay) & 0xFFFF;
-
-       if (weird_number_of_bits && bits_left < 16) {
-           outval <<= bits_left;
-           outval |= t >> (16 - bits_left);
-           thisline_changed |= *dataptr ^ outval;
-           *dataptr++ = outval;
-
-           outval = t;
-           tmp_nbits = 16 - bits_left;
-           shiftbuffer <<= 16;
-       } else {
-           outval = (outval << 16) | t;
-           shiftbuffer <<= 16;
-           tmp_nbits += 16;
-           if (tmp_nbits == 32) {
-               thisline_changed |= *dataptr ^ outval;
-               *dataptr++ = outval;
-               tmp_nbits = 0;
-           }
-       }
-       nwords--;
-       if (dma) {
-           fetchval = do_get_mem_word (real_pt);
-           real_pt++;
-       }
-    }
-    fetched[plane] = fetchval;
-    todisplay[plane][0] = shiftbuffer;
-    outword[plane] = outval;
-}
-
-#ifdef AGA
-STATIC_INLINE void long_fetch_aga (int plane, int nwords, int weird_number_of_bits, int fm, int dma)
-{
-    uae_u32 *real_pt = (uae_u32 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2);
-    int delay = (plane & 1) ? toscr_delay2 : toscr_delay1;
-    int tmp_nbits = out_nbits;
-    uae_u32 *shiftbuffer = todisplay[plane];
-    uae_u32 outval = outword[plane];
-    uae_u32 fetchval0 = fetched_aga0[plane];
-    uae_u32 fetchval1 = fetched_aga1[plane];
-    uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs);
-    int offs = (16 << fm) - 16 + delay;
-    int off1 = offs >> 5;
-    if (off1 == 3)
-       off1 = 2;
-    offs -= off1 * 32;
-
-    if (dma)
-       bplpt[plane] += nwords * 2;
-
-    if (real_pt == 0)
-       /* @@@ Don't do this, fall back on chipmem_wget instead.  */
-       return;
-
-    while (nwords > 0) {
-       int i;
-
-       shiftbuffer[0] = fetchval0;
-       if (fm == 2)
-           shiftbuffer[1] = fetchval1;
-
-       for (i = 0; i < (1 << fm); i++) {
-           int bits_left = 32 - tmp_nbits;
-
-           uae_u32 t0 = shiftbuffer[off1];
-           uae_u32 t1 = shiftbuffer[off1 + 1];
-           uae_u64 t = (((uae_u64)t1) << 32) | t0;
-
-           t0 = (uae_u32)((t >> offs) & 0xFFFF);
-
-           if (weird_number_of_bits && bits_left < 16) {
-               outval <<= bits_left;
-               outval |= t0 >> (16 - bits_left);
-
-               thisline_changed |= *dataptr ^ outval;
-               *dataptr++ = outval;
-
-               outval = t0;
-               tmp_nbits = 16 - bits_left;
-               aga_shift (shiftbuffer, 16, fm);
-           } else {
-               outval = (outval << 16) | t0;
-               aga_shift (shiftbuffer, 16, fm);
-               tmp_nbits += 16;
-               if (tmp_nbits == 32) {
-                   thisline_changed |= *dataptr ^ outval;
-                   *dataptr++ = outval;
-                   tmp_nbits = 0;
-               }
-           }
-       }
-
-       nwords -= 1 << fm;
-
-       if (dma) {
-           if (fm == 1)
-               fetchval0 = do_get_mem_long (real_pt);
-           else {
-               fetchval1 = do_get_mem_long (real_pt);
-               fetchval0 = do_get_mem_long (real_pt + 1);
-           }
-           real_pt += fm;
-       }
-    }
-    fetched_aga0[plane] = fetchval0;
-    fetched_aga1[plane] = fetchval1;
-    outword[plane] = outval;
-}
-#endif
-
-static void long_fetch_ecs_0 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 0, dma); }
-static void long_fetch_ecs_1 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 1, dma); }
-#ifdef AGA
-static void long_fetch_aga_1_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords,  0, 1, dma); }
-static void long_fetch_aga_1_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords,  1, 1, dma); }
-static void long_fetch_aga_2_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords,  0, 2, dma); }
-static void long_fetch_aga_2_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords,  1, 2, dma); }
-#endif
-
-static void do_long_fetch (int hpos, int nwords, int dma, int fm)
-{
-    int i;
-
-    flush_display (fm);
-    switch (fm) {
-    case 0:
-       if (out_nbits & 15) {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_ecs_1 (i, nwords, dma);
-       } else {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_ecs_0 (i, nwords, dma);
-       }
-       break;
-#ifdef AGA
-    case 1:
-       if (out_nbits & 15) {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_aga_1_1 (i, nwords, dma);
-       } else {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_aga_1_0 (i, nwords, dma);
-       }
-       break;
-    case 2:
-       if (out_nbits & 15) {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_aga_2_1 (i, nwords, dma);
-       } else {
-           for (i = 0; i < toscr_nr_planes; i++)
-               long_fetch_aga_2_0 (i, nwords, dma);
-       }
-       break;
-#endif
-    }
-
-    out_nbits += nwords * 16;
-    out_offs += out_nbits >> 5;
-    out_nbits &= 31;
-
-    if (dma && toscr_nr_planes > 0)
-       fetch_state = fetch_was_plane0;
-}
-
-#endif
-
-/* make sure fetch that goes beyond maxhpos is finished */
-static void finish_final_fetch (int i, int fm)
-{
-    if (thisline_decision.plfleft == -1)
-       return;
-    if (passed_plfstop == 3)
-       return;
-    passed_plfstop = 3;
-    ddfstate = DIW_waiting_start;
-    i += flush_plane_data (fm);
-    thisline_decision.plfright = i;
-    thisline_decision.plflinelen = out_offs;
-    thisline_decision.bplres = toscr_res_first;
-    finish_playfield_line ();
-}
-
-STATIC_INLINE int one_fetch_cycle_0 (int i, int ddfstop_to_test, int dma, int fm)
-{
-    if (! passed_plfstop && i == ddfstop_to_test)
-       passed_plfstop = 1;
-
-    if ((fetch_cycle & fetchunit_mask) == 0) {
-       if (passed_plfstop == 2) {
-           finish_final_fetch (i, fm);
-           return 1;
-       }
-       if (passed_plfstop)
-           passed_plfstop++;
-    }
-
-    if (dma) {
-       /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0.  This means
-          that the remaining cycles are idle; we'll fall through the whole switch
-          without doing anything.  */
-       int cycle_start = fetch_cycle & fetchstart_mask;
-       switch (fm_maxplane) {
-       case 8:
-           switch (cycle_start) {
-           case 0: fetch (7, fm); break;
-           case 1: fetch (3, fm); break;
-           case 2: fetch (5, fm); break;
-           case 3: fetch (1, fm); break;
-           case 4: fetch (6, fm); break;
-           case 5: fetch (2, fm); break;
-           case 6: fetch (4, fm); break;
-           case 7: fetch (0, fm); break;
-           }
-           break;
-       case 4:
-           switch (cycle_start) {
-           case 0: fetch (3, fm); break;
-           case 1: fetch (1, fm); break;
-           case 2: fetch (2, fm); break;
-           case 3: fetch (0, fm); break;
-           }
-           break;
-       case 2:
-           switch (cycle_start) {
-           case 0: fetch (1, fm); break;
-           case 1: fetch (0, fm); break;
-           }
-           break;
-       }
-    }
-    fetch_cycle++;
-    toscr_nbits += 2 << toscr_res;
-
-    if (toscr_nbits == 16)
-       flush_display (fm);
-    if (toscr_nbits > 16)
-       uae_abort ("toscr_nbits > 16 (%d)", toscr_nbits);
-
-    return 0;
-}
-
-static int one_fetch_cycle_fm0 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 0); }
-static int one_fetch_cycle_fm1 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 1); }
-static int one_fetch_cycle_fm2 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 2); }
-
-STATIC_INLINE int one_fetch_cycle (int i, int ddfstop_to_test, int dma, int fm)
-{
-    switch (fm) {
-    case 0: return one_fetch_cycle_fm0 (i, ddfstop_to_test, dma);
-#ifdef AGA
-    case 1: return one_fetch_cycle_fm1 (i, ddfstop_to_test, dma);
-    case 2: return one_fetch_cycle_fm2 (i, ddfstop_to_test, dma);
-#endif
-    default: uae_abort ("fm corrupt"); return 0;
-    }
-}
-
-STATIC_INLINE void update_fetch (int until, int fm)
-{
-    int pos;
-    int dma = dmaen (DMA_BITPLANE);
-
-    int ddfstop_to_test;
-
-    if (framecnt != 0 || passed_plfstop == 3)
-       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;
-
-    compute_toscr_delay (last_fetch_hpos);
-    update_toscr_planes ();
-
-    pos = last_fetch_hpos;
-    cycle_diagram_shift = last_fetch_hpos - fetch_cycle;
-
-    /* First, a loop that prepares us for the speedup code.  We want to enter
-       the SPEEDUP case with fetch_state == fetch_was_plane0, and then unroll
-       whole blocks, so that we end on the same fetch_state again.  */
-    for (; ; pos++) {
-       if (pos == until) {
-           if (until >= maxhpos) {
-               finish_final_fetch (pos, fm);
-               return;
-           }
-           flush_display (fm);
-           return;
-       }
-
-       if (fetch_state == fetch_was_plane0)
-           break;
-
-       fetch_state = fetch_started;
-       if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm))
-           return;
-    }
-
-#ifdef SPEEDUP
-    /* Unrolled version of the for loop below.  */
-    if (! passed_plfstop && ddf_change != vpos && ddf_change + 1 != vpos
-       && dma
-       && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask)
-       && toscr_delay1 == toscr_delay1x && toscr_delay2 == toscr_delay2x
- # if 0
-       /* @@@ We handle this case, but the code would be simpler if we
-        * disallowed it - it may even be possible to guarantee that
-        * this condition never is false.  Later.  */
-       && (out_nbits & 15) == 0
-# endif
-       && toscr_nr_planes == thisline_decision.nr_planes)
-    {
-       int offs = (pos - fetch_cycle) & fetchunit_mask;
-       int ddf2 = ((ddfstop_to_test - offs + fetchunit - 1) & ~fetchunit_mask) + offs;
-       int ddf3 = ddf2 + fetchunit;
-       int stop = until < ddf2 ? until : until < ddf3 ? ddf2 : ddf3;
-       int count;
-
-       count = stop - pos;
-
-       if (count >= fetchstart) {
-           count &= ~fetchstart_mask;
-
-           if (thisline_decision.plfleft == -1) {
-               compute_delay_offset ();
-               compute_toscr_delay_1 ();
-           }
-           do_long_fetch (pos, count >> (3 - toscr_res), dma, fm);
-
-           /* This must come _after_ do_long_fetch so as not to confuse flush_display
-              into thinking the first fetch has produced any output worth emitting to
-              the screen.  But the calculation of delay_offset must happen _before_.  */
-           maybe_first_bpl1dat (pos);
-
-           if (pos <= ddfstop_to_test && pos + count > ddfstop_to_test)
-               passed_plfstop = 1;
-           if (pos <= ddfstop_to_test && pos + count > ddf2)
-               passed_plfstop = 2;
-           if (pos <= ddf2 && pos + count >= ddf2 + fm_maxplane)
-               add_modulos ();
-           pos += count;
-           fetch_cycle += count;
-       }
-    }
-#endif
-    for (; pos < until; pos++) {
-       if (fetch_state == fetch_was_plane0)
-           beginning_of_plane_block (pos, fm);
-       fetch_state = fetch_started;
-
-       if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm))
-           return;
-    }
-    if (until >= maxhpos) {
-       finish_final_fetch (pos, fm);
-       return;
-    }
-    flush_display (fm);
-}
-
-static void update_fetch_0 (int hpos) { update_fetch (hpos, 0); }
-static void update_fetch_1 (int hpos) { update_fetch (hpos, 1); }
-static void update_fetch_2 (int hpos) { update_fetch (hpos, 2); }
-
-STATIC_INLINE void decide_fetch (int hpos)
-{
-    if (fetch_state != fetch_not_started && hpos > last_fetch_hpos) {
-       switch (fetchmode) {
-       case 0: update_fetch_0 (hpos); break;
-#ifdef AGA
-       case 1: update_fetch_1 (hpos); break;
-       case 2: update_fetch_2 (hpos); break;
-#endif
-       default: uae_abort ("fetchmode corrupt");
-       }
-    }
-    last_fetch_hpos = hpos;
-}
-
-static void start_bpl_dma (int hpos, int hstart)
-{
-    fetch_state = fetch_started;
-    fetch_cycle = 0;
-    last_fetch_hpos = hstart;
-    out_nbits = 0;
-    out_offs = 0;
-    toscr_nbits = 0;
-    toscr_res_first = GET_RES (bplcon0);
-
-    ddfstate = DIW_waiting_stop;
-    compute_toscr_delay (last_fetch_hpos);
-
-    /* If someone already wrote BPL1DAT, clear the area between that point and
-       the real fetch start.  */
-    if (framecnt == 0) {
-       if (thisline_decision.plfleft != -1) {
-           out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res);
-           out_offs = out_nbits >> 5;
-           out_nbits &= 31;
-       }
-       update_toscr_planes ();
-    }
-}
-
-/* this may turn on datafetch if program turns dma on during the ddf */
-static void maybe_start_bpl_dma (int hpos)
-{
-    /* OCS: BPL DMA never restarts if DMA is turned on during DDF
-     * ECS/AGA: BPL DMA restarts but only if DMA was turned off
-       outside of DDF or during current line, otherwise display
-       processing jumps immediately to "DDFSTOP passed"-condition */
-    if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       return;
-    if (fetch_state != fetch_not_started)
-       return;
-    if (diwstate != DIW_waiting_stop)
-       return;
-    if (hpos <= plfstrt)
-       return;
-    if (hpos > plfstop)
-       return;
-    if (ddfstate != DIW_waiting_start)
-        passed_plfstop = 1;
-    start_bpl_dma (hpos, hpos);
-}
-
-/* This function is responsible for turning on datafetch if necessary.  */
-STATIC_INLINE void decide_line (int hpos)
-{
-    /* Take care of the vertical DIW.  */
-    if (vpos == plffirstline)
-       diwstate = DIW_waiting_stop;
-    if (vpos == plflastline)
-       diwstate = DIW_waiting_start;
-
-    if (hpos <= last_decide_line_hpos)
-       return;
-    if (fetch_state != fetch_not_started)
-       return;
-
-    if (dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) {
-       int ok = 0;
-        /* Test if we passed the start of the DDF window.  */
-       if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
-           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 (ddfstrt_old != ddfstrt && hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos)
-               ok = 0;
-           if (ok) {
-               start_bpl_dma (hpos, plfstrt);
-               estimate_last_fetch_cycle (plfstrt);
-               last_decide_line_hpos = hpos;
-#ifndef CUSTOM_SIMPLE
-               do_sprites (plfstrt);
-#endif
-               return;
-           }
-       }
-    }
-
-#ifndef CUSTOM_SIMPLE
-    if (last_decide_line_hpos < SPR0_HPOS + 4 * MAX_SPRITES)
-       do_sprites (hpos);
-#endif
-    last_decide_line_hpos = hpos;
-}
-
-/* Called when a color is about to be changed (write to a color register),
- * but the new color has not been entered into the table yet. */
-static void record_color_change (int hpos, int regno, unsigned long value)
-{
-    if (regno == -1 && value) {
-       thisline_decision.ham_seen = 1;
-       if (hpos < HARD_DDF_START)
-           thisline_decision.ham_at_start = 1;
-    }
-
-    /* Early positions don't appear on-screen. */
-    if (framecnt != 0 || vpos < minfirstline || hpos < HARD_DDF_START
-       /*|| currprefs.emul_accuracy == 0*/)
-       return;
-
-    decide_diw (hpos);
-    decide_line (hpos);
-
-    if (thisline_decision.ctable == -1)
-       remember_ctable ();
-
-#ifdef OS_WITHOUT_MEMORY_MANAGEMENT
-    if (next_color_change >= max_color_change) {
-       ++delta_color_change;
-       return;
-    }
-#endif
-    curr_color_changes[next_color_change].linepos = hpos;
-    curr_color_changes[next_color_change].regno = regno;
-    curr_color_changes[next_color_change++].value = value;
-}
-
-typedef int sprbuf_res_t, cclockres_t, hwres_t, bplres_t;
-
-static void do_playfield_collisions (void)
-{
-    uae_u8 *ld = line_data[next_lineno];
-    int i;
-
-    if (clxcon_bpl_enable == 0) {
-       clxdat |= 1;
-       return;
-    }
-       
-    for (i = thisline_decision.plfleft; i < thisline_decision.plfright; i += 2) {
-       int j;
-       uae_u32 total = 0xFFFFFFFF;
-       for (j = 0; j < 8; j++) {
-           uae_u32 t = 0;
-           if ((clxcon_bpl_enable & (1 << j)) == 0)
-               t = 0xFFFFFFFF;
-           else if (j < thisline_decision.nr_planes) {
-               t = *(uae_u32 *)(line_data[next_lineno] + 2 * i + 2 * j * MAX_WORDS_PER_LINE);
-               t ^= ~(((clxcon_bpl_match >> j) & 1) - 1);
-           }
-           total &= t;
-       }
-       if (total)
-           clxdat |= 1;        
-    }
-}
-
-/* Sprite-to-sprite collisions are taken care of in record_sprite.  This one does
-   playfield/sprite collisions.
-   That's the theory.  In practice this doesn't work yet.  I also suspect this code
-   is way too slow.  */
-static void do_sprite_collisions (void)
-{
-    int nr_sprites = curr_drawinfo[next_lineno].nr_sprites;
-    int first = curr_drawinfo[next_lineno].first_sprite_entry;
-    int i;
-    unsigned int collision_mask = clxmask[clxcon >> 12];
-    int bplres = GET_RES (bplcon0);
-    hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres;
-    hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword);
-    hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword);
-
-    if (clxcon_bpl_enable == 0) {
-       clxdat |= 0x1FE;
-       return;
-    }
-
-    for (i = 0; i < nr_sprites; i++) {
-       struct sprite_entry *e = curr_sprite_entries + first + i;
-       sprbuf_res_t j;
-       sprbuf_res_t minpos = e->pos;
-       sprbuf_res_t maxpos = e->max;
-       hwres_t minp1 = minpos >> sprite_buffer_res;
-       hwres_t maxp1 = maxpos >> sprite_buffer_res;
-
-       if (maxp1 > hw_diwlast)
-           maxpos = hw_diwlast << sprite_buffer_res;
-       if (maxp1 > thisline_decision.plfright * 2)
-           maxpos = thisline_decision.plfright * 2 << sprite_buffer_res;
-       if (minp1 < hw_diwfirst)
-           minpos = hw_diwfirst << sprite_buffer_res;
-       if (minp1 < thisline_decision.plfleft * 2)
-           minpos = thisline_decision.plfleft * 2 << sprite_buffer_res;
-
-       for (j = minpos; j < maxpos; j++) {
-           int sprpix = spixels[e->first_pixel + j - e->pos] & collision_mask;
-           int k, offs, match = 1;
-
-           if (sprpix == 0)
-               continue;
-
-           offs = ((j << bplres) >> sprite_buffer_res) - ddf_left;
-           sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2);
-           sprpix <<= 1;
-
-           /* Loop over number of playfields.  */
-           for (k = 1; k >= 0; k--) {
-               int l;
-#ifdef AGA
-               int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6;
-#else
-               int planes = 6;
-#endif
-               if (bplcon0 & 0x400)
-                   match = 1;
-               for (l = k; match && l < planes; l += 2) {
-                   int t = 0;
-                   if (l < thisline_decision.nr_planes) {
-                       uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE);
-                       uae_u32 word = ldata[offs >> 5];
-                       t = (word >> (31 - (offs & 31))) & 1;
-#if 0 /* debug: draw collision mask */
-                       if (1) {
-                           int m;
-                           for (m = 0; m < 5; m++) {
-                               ldata = (uae_u32 *)(line_data[next_lineno] + 2 * m * MAX_WORDS_PER_LINE);
-                               ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31));
-                           }
-                       }
-#endif
-                   }
-                   if (clxcon_bpl_enable & (1 << l)) {
-                       if (t != ((clxcon_bpl_match >> l) & 1))
-                           match = 0;
-                   }
-               }
-               if (match) {
-#if 0 /* debug: mark lines where collisions are detected */
-                   if (0) {
-                       int l;
-                       for (l = 0; l < 5; l++) {
-                           uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE);
-                           ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31));
-                       }
-                   }
-#endif
-                   clxdat |= sprpix << (k * 4);
-               }
-           }
-       }
-    }
-#if 0
-    {
-       static int olx;
-       if (clxdat != olx)
-           write_log ("%d: %04.4X\n", vpos, clxdat);
-       olx = clxdat;
-    }
-#endif
-}
-
-static void expand_sprres (void)
-{
-    switch ((bplcon3 >> 6) & 3) {
-    case 0: /* ECS defaults (LORES,HIRES=140ns,SHRES=70ns) */
-       if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES (bplcon0) == RES_SUPERHIRES)
-           sprres = RES_HIRES;
-       else
-           sprres = RES_LORES;
-       break;
-    case 1:
-       sprres = RES_LORES;
-       break;
-    case 2:
-       sprres = RES_HIRES;
-       break;
-    case 3:
-       sprres = RES_SUPERHIRES;
-       break;
-    }
-}
-
-STATIC_INLINE void record_sprite_1 (uae_u16 *buf, uae_u32 datab, int num, int dbl,
-                                   unsigned int mask, int do_collisions, uae_u32 collision_mask)
-{
-    int j = 0;
-    while (datab) {
-       unsigned int tmp = *buf;
-       unsigned int col = (datab & 3) << (2 * num);
-       tmp |= col;
-       if ((j & mask) == 0)
-           *buf++ = tmp;
-       if (dbl)
-           *buf++ = tmp;
-       j++;
-       datab >>= 2;
-       if (do_collisions) {
-           tmp &= collision_mask;
-           if (tmp) {
-               unsigned int shrunk_tmp = sprite_ab_merge[tmp & 255] | (sprite_ab_merge[tmp >> 8] << 2);
-               clxdat |= sprclx[shrunk_tmp];
-           }
-       }
-    }
-}
-
-/* DATAB contains the sprite data; 16 pixels in two-bit packets.  Bits 0/1
-   determine the color of the leftmost pixel, bits 2/3 the color of the next
-   etc.
-   This function assumes that for all sprites in a given line, SPRXP either
-   stays equal or increases between successive calls.
-
-   The data is recorded either in lores pixels (if ECS), or in hires pixels
-   (if AGA).  No support for SHRES sprites.  */
-
-static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl)
-{
-    struct sprite_entry *e = curr_sprite_entries + next_sprite_entry;
-    int i;
-    int word_offs;
-    uae_u16 *buf;
-    uae_u32 collision_mask;
-    int width = sprite_width;
-    int dbl = 0, half = 0;
-    unsigned int mask = 0;
-
-    if (sprres != RES_LORES)
-       thisline_decision.any_hires_sprites = 1;
-
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA) {
-       width = (width << 1) >> sprres;
-       dbl = sprite_buffer_res - sprres;
-       if (dbl < 0) {
-           half = -dbl;
-           dbl = 0;
-       }
-       mask = sprres == RES_SUPERHIRES ? 1 : 0;
-    }
-#endif
-
-    /* Try to coalesce entries if they aren't too far apart.  */
-    if (! next_sprite_forced && e[-1].max + 16 >= sprxp) {
-       e--;
-    } else {
-       next_sprite_entry++;
-       e->pos = sprxp;
-       e->has_attached = 0;
-    }
-
-    if (sprxp < e->pos)
-       uae_abort ("sprxp < e->pos");
-
-    e->max = sprxp + width;
-    e[1].first_pixel = e->first_pixel + ((e->max - e->pos + 3) & ~3);
-    next_sprite_forced = 0;
-
-    collision_mask = clxmask[clxcon >> 12];
-    word_offs = e->first_pixel + sprxp - e->pos;
-
-    for (i = 0; i < sprite_width; i += 16) {
-       unsigned int da = *data;
-       unsigned int db = *datb;
-       uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8]
-                        | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]);
-
-       buf = spixels + word_offs + ((i << dbl) >> half);
-       if (currprefs.collision_level > 0 && collision_mask)
-           record_sprite_1 (buf, datab, num, dbl, mask, 1, collision_mask);
-       else
-           record_sprite_1 (buf, datab, num, dbl, mask, 0, collision_mask);
-       data++;
-       datb++;
-    }
-
-    /* We have 8 bits per pixel in spixstate, two for every sprite pair.  The
-       low order bit records whether the attach bit was set for this pair.  */
-
-    if (ctl & 0x80) {
-       uae_u32 state = 0x01010101 << (num & ~1);
-       uae_u32 *stbuf = spixstate.words + (word_offs >> 2);
-       uae_u8 *stb1 = spixstate.bytes + word_offs;     
-       for (i = 0; i < width; i += 8) {
-           stb1[0] |= state;
-           stb1[1] |= state;
-           stb1[2] |= state;
-           stb1[3] |= state;
-           stb1[4] |= state;
-           stb1[5] |= state;
-           stb1[6] |= state;
-           stb1[7] |= state;
-           stb1 += 8;
-       }
-       e->has_attached = 1;
-    }
-}
-
-static void decide_sprites (int hpos)
-{
-    int nrs[MAX_SPRITES], posns[MAX_SPRITES];
-    int count, i;
-    int point = hpos * 2;
-    int width = sprite_width;
-    int window_width = (width << lores_shift) >> sprres;
-
-    if (framecnt != 0 || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
-       return;
-#ifdef DISABLE_SPRITES
-    return;
-#endif
-
-    decide_diw (hpos);
-    decide_line (hpos);
-
-#if 0
-    /* This tries to detect whether the line is border, but that doesn't work, it's too early.  */
-    if (thisline_decision.plfleft == -1)
-       return;
-#endif
-    count = 0;
-    for (i = 0; i < MAX_SPRITES; i++) {
-       int sprxp = spr[i].xpos;
-       int hw_xp = (sprxp >> sprite_buffer_res);
-       int window_xp = coord_hw_to_window_x (hw_xp) + (DIW_DDF_OFFSET << lores_shift);
-       int j, bestp;
-
-       if (! spr[i].armed || sprxp < 0 || hw_xp <= last_sprite_point || hw_xp > point)
-           continue;
-       if ( !(bplcon3 & 2) && /* sprites outside playfields enabled? */
-           ((thisline_decision.diwfirstword >= 0 && window_xp + window_width < thisline_decision.diwfirstword)
-           || (thisline_decision.diwlastword >= 0 && window_xp > thisline_decision.diwlastword)))
-           continue;
-
-       /* Sort the sprites in order of ascending X position before recording them.  */
-       for (bestp = 0; bestp < count; bestp++) {
-           if (posns[bestp] > sprxp)
-               break;
-           if (posns[bestp] == sprxp && nrs[bestp] < i)
-               break;
-       }
-       for (j = count; j > bestp; j--) {
-           posns[j] = posns[j-1];
-           nrs[j] = nrs[j-1];
-       }
-       posns[j] = sprxp;
-       nrs[j] = i;
-       count++;
-    }
-    for (i = 0; i < count; i++) {
-       int nr = nrs[i];    
-       record_sprite (next_lineno, nr, spr[nr].xpos, sprdata[nr], sprdatb[nr], sprctl[nr]);
-    }
-    last_sprite_point = point;
-}
-
-STATIC_INLINE int sprites_differ (struct draw_info *dip, struct draw_info *dip_old)
-{
-    struct sprite_entry *this_first = curr_sprite_entries + dip->first_sprite_entry;
-    struct sprite_entry *this_last = curr_sprite_entries + dip->last_sprite_entry;
-    struct sprite_entry *prev_first = prev_sprite_entries + dip_old->first_sprite_entry;
-    int npixels;
-    int i;
-
-    if (dip->nr_sprites != dip_old->nr_sprites)
-       return 1;
-    
-    if (dip->nr_sprites == 0)
-       return 0;
-
-    for (i = 0; i < dip->nr_sprites; i++)
-       if (this_first[i].pos != prev_first[i].pos
-           || this_first[i].max != prev_first[i].max
-           || this_first[i].has_attached != prev_first[i].has_attached)
-           return 1;
-
-    npixels = this_last->first_pixel + (this_last->max - this_last->pos) - this_first->first_pixel;
-    if (memcmp (spixels + this_first->first_pixel, spixels + prev_first->first_pixel,
-               npixels * sizeof (uae_u16)) != 0)
-       return 1;
-    if (memcmp (spixstate.bytes + this_first->first_pixel, spixstate.bytes + prev_first->first_pixel, npixels) != 0)
-       return 1;
-    return 0;
-}
-
-STATIC_INLINE int color_changes_differ (struct draw_info *dip, struct draw_info *dip_old)
-{
-    if (dip->nr_color_changes != dip_old->nr_color_changes)
-       return 1;
-    
-    if (dip->nr_color_changes == 0)
-       return 0;
-    if (memcmp (curr_color_changes + dip->first_color_change,
-               prev_color_changes + dip_old->first_color_change,
-               dip->nr_color_changes * sizeof *curr_color_changes) != 0)
-       return 1;
-    return 0;
-}
-
-/* End of a horizontal scan line. Finish off all decisions that were not
- * made yet. */
-static void finish_decisions (void)
-{
-    struct draw_info *dip;
-    struct draw_info *dip_old;
-    struct decision *dp;
-    int changed;
-    int hpos = current_hpos ();
-
-    if (framecnt != 0)
-       return;
-
-    decide_diw (hpos);
-    decide_line (hpos);
-    decide_fetch (hpos);
-
-    if (thisline_decision.plfleft != -1 && thisline_decision.plflinelen == -1) {
-       if (fetch_state != fetch_not_started) {
-           write_log("fetch_state=%d plfleft=%d\n",fetch_state,thisline_decision.plfleft);
-           uae_abort ("fetch_state != fetch_not_started");
-       }
-       thisline_decision.plfright = thisline_decision.plfleft;
-       thisline_decision.plflinelen = 0;
-       thisline_decision.bplres = RES_LORES;
-    }
-
-    /* Large DIWSTOP values can cause the stop position never to be
-     * reached, so the state machine always stays in the same state and
-     * there's a more-or-less full-screen DIW. */
-    if (hdiwstate == DIW_waiting_stop || thisline_decision.diwlastword > max_diwlastword)
-       thisline_decision.diwlastword = max_diwlastword;
-
-    if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword)
-       MARK_LINE_CHANGED;
-    if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword)
-       MARK_LINE_CHANGED;
-
-    dip = curr_drawinfo + next_lineno;
-    dip_old = prev_drawinfo + next_lineno;
-    dp = line_decisions + next_lineno;
-    changed = thisline_changed;
-
-    if (thisline_decision.plfleft != -1) {
-       record_diw_line (thisline_decision.diwfirstword, thisline_decision.diwlastword);
-
-       decide_sprites (hpos);
-    }
-
-    dip->last_sprite_entry = next_sprite_entry;
-    dip->last_color_change = next_color_change;
-
-    if (thisline_decision.ctable == -1) {
-       if (thisline_decision.plfleft == -1)
-           remember_ctable_for_border ();
-       else
-           remember_ctable ();
-    }
-
-    dip->nr_color_changes = next_color_change - dip->first_color_change;
-    dip->nr_sprites = next_sprite_entry - dip->first_sprite_entry;
-
-    if (thisline_decision.plfleft != line_decisions[next_lineno].plfleft)
-       changed = 1;
-    if (! changed && color_changes_differ (dip, dip_old))
-       changed = 1;
-    if (!changed && thisline_decision.plfleft != -1 && sprites_differ (dip, dip_old))
-       changed = 1;
-
-    if (changed) {
-       thisline_changed = 1;
-       *dp = thisline_decision;
-    } else
-       /* The only one that may differ: */
-       dp->ctable = thisline_decision.ctable;
-}
-
-/* Set the state of all decisions to "undecided" for a new scanline. */
-static void reset_decisions (void)
-{
-    if (framecnt != 0)
-       return;
-    toscr_res_first = 0;
-
-    thisline_decision.any_hires_sprites = 0;
-    thisline_decision.nr_planes = 0;
-
-    thisline_decision.plfleft = -1;
-    thisline_decision.plflinelen = -1;
-    thisline_decision.ham_seen = !! (bplcon0 & 0x800);
-    thisline_decision.ham_at_start = !! (bplcon0 & 0x800);
-
-    /* decided_res shouldn't be touched before it's initialized by decide_line(). */
-    thisline_decision.diwfirstword = -1;
-    thisline_decision.diwlastword = -1;
-    if (hdiwstate == DIW_waiting_stop) {
-       thisline_decision.diwfirstword = 0;
-       if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword)
-           MARK_LINE_CHANGED;
-    }
-    thisline_decision.ctable = -1;
-
-    thisline_changed = 0;
-    curr_drawinfo[next_lineno].first_color_change = next_color_change;
-    curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry;
-    next_sprite_forced = 1;
-
-    /* memset(sprite_last_drawn_at, 0, sizeof sprite_last_drawn_at); */
-    last_sprite_point = 0;
-    fetch_state = fetch_not_started;
-    passed_plfstop = 0;
-
-    memset (todisplay, 0, sizeof todisplay);
-    memset (fetched, 0, sizeof fetched);
-#ifdef AGA
-    memset (fetched_aga0, 0, sizeof fetched_aga0);
-    memset (fetched_aga1, 0, sizeof fetched_aga1);
-#endif
-    memset (outword, 0, sizeof outword);
-
-    last_decide_line_hpos = -1;
-    last_diw_pix_hpos = -1;
-    last_ddf_pix_hpos = -1;
-    last_sprite_hpos = -1;
-    last_fetch_hpos = -1;
-
-}
-
-int vsynctime_orig;
-int turbo_emulation;
-
-void compute_vsynctime (void)
-{
-    fake_vblank_hz = 0;
-    if (currprefs.gfx_vsync && currprefs.gfx_afullscreen && currprefs.gfx_refreshrate) {
-       vblank_hz = currprefs.gfx_refreshrate;
-       vblank_skip = 1;
-#if 0
-       if (vblank_hz == 75) {
-           fake_vblank_hz = 50;
-           vblank_skip = 2;
-       }
-       if (vblank_hz == 90) {
-           fake_vblank_hz = 60;
-           vblank_skip = 2;
-       }
-#endif
-       if (!fake_vblank_hz && vblank_hz > 85) {
-           vblank_hz /= 2;
-           vblank_skip = -1;
-       }
-    }
-    if (!fake_vblank_hz)
-        fake_vblank_hz = vblank_hz;
-    if (turbo_emulation)
-       vsynctime = vsynctime_orig = 1;
-    else
-       vsynctime = vsynctime_orig = syncbase / fake_vblank_hz;
-#ifdef OPENGL
-    OGL_refresh ();
-#endif
-#ifdef D3D
-    D3D_refresh ();
-#endif
-    if (currprefs.produce_sound > 1)
-       update_sound (fake_vblank_hz);
-}
-
-
-/* set PAL or NTSC timing variables */
-void init_hz (void)
-{
-    int isntsc;
-
-    beamcon0 = new_beamcon0;
-    isntsc = beamcon0 & 0x20 ? 0 : 1;
-    if (hack_vpos > 0) {
-       if (maxvpos == hack_vpos) return;
-       maxvpos = hack_vpos;
-       vblank_hz = 15600 / hack_vpos;
-       hack_vpos = -1;
-    } else if (hack_vpos < 0) {
-       hack_vpos = 0;
-    }
-    if (hack_vpos == 0) {
-       if (!isntsc) {
-           maxvpos = MAXVPOS_PAL;
-           maxhpos = MAXHPOS_PAL;
-           minfirstline = VBLANK_ENDLINE_PAL;
-           vblank_hz = VBLANK_HZ_PAL;
-           sprite_vblank_endline = VBLANK_SPRITE_PAL;
-       } else {
-           maxvpos = MAXVPOS_NTSC;
-           maxhpos = MAXHPOS_NTSC;
-           minfirstline = VBLANK_ENDLINE_NTSC;
-           vblank_hz = VBLANK_HZ_NTSC;
-           sprite_vblank_endline = VBLANK_SPRITE_NTSC;
-       }
-    }
-    if (beamcon0 & 0x80) {
-       if (vtotal >= MAXVPOS)
-           vtotal = MAXVPOS - 1;
-       maxvpos = vtotal + 1;
-       if (htotal >= MAXHPOS)
-           htotal = MAXHPOS - 1;
-       maxhpos = htotal + 1;
-       vblank_hz = 227 * 312 * 50 / (maxvpos * maxhpos);
-    }
-    /* limit to sane values */
-    if (vblank_hz < 10)
-       vblank_hz = 10;
-    if (vblank_hz > 300)
-       vblank_hz = 300;
-    eventtab[ev_hsync].oldcycles = get_cycles ();
-    eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME;
-    events_schedule ();
-    compute_vsynctime ();
-#ifdef OPENGL
-    OGL_refresh ();
-#endif
-#ifdef PICASSO96
-    init_hz_p96 ();
-#endif
-    write_log ("%s mode, %dHz\n", isntsc ? "NTSC" : "PAL", vblank_hz);
-}
-
-static void calcdiw (void)
-{
-    int hstrt = diwstrt & 0xFF;
-    int hstop = diwstop & 0xFF;
-    int vstrt = diwstrt >> 8;
-    int vstop = diwstop >> 8;
-
-    if (diwhigh_written) {
-       hstrt |= ((diwhigh >> 5) & 1) << 8;
-       hstop |= ((diwhigh >> 13) & 1) << 8;
-       vstrt |= (diwhigh & 7) << 8;
-       vstop |= ((diwhigh >> 8) & 7) << 8;
-    } else {
-       hstop += 0x100;
-       if ((vstop & 0x80) == 0)
-           vstop |= 0x100;
-    }
-
-    diwfirstword = coord_diw_to_window_x (hstrt);
-    diwlastword = coord_diw_to_window_x (hstop);
-    if (diwfirstword < 0)
-       diwfirstword = 0;
-
-    plffirstline = vstrt;
-    plflastline = vstop;
-
-#if 0
-    /* This happens far too often. */
-    if (plffirstline < minfirstline_bpl) {
-       write_log ("Warning: Playfield begins before line %d (%d)!\n", minfirstline_bpl, plffirstline);
-    }
-#endif
-
-#if 0 /* this comparison is not needed but previous is.. */
-    if (plflastline > 313) {
-       /* Turrican does this */
-       write_log ("Warning: Playfield out of range!\n");
-       plflastline = 313;
-    }
-#endif
-
-    plfstrt = ddfstrt;
-    plfstop = ddfstop;
-    /* probably not the correct place.. */
-    if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && ddfstop > maxhpos)
-       plfstrt = 0;
-    if (plfstrt < HARD_DDF_START)
-       plfstrt = HARD_DDF_START;
-}
-
-static int timehack_alive = 0;
-
-static uae_u32 timehack_helper (void)
-{
-#ifdef HAVE_GETTIMEOFDAY
-    struct timeval tv;
-    if (m68k_dreg (regs, 0) == 0)
-       return timehack_alive;
-
-    timehack_alive = 10;
-
-    gettimeofday (&tv, NULL);
-    put_long (m68k_areg (regs, 0), tv.tv_sec - (((365 * 8 + 2) * 24) * 60 * 60));
-    put_long (m68k_areg (regs, 0) + 4, tv.tv_usec);
-    return 0;
-#else
-    return 2;
-#endif
-}
-
- /*
-  * register functions
-  */
-STATIC_INLINE uae_u16 DENISEID (void)
-{
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA)
-       return 0xF8;
-#endif
-    if (currprefs.chipset_mask & CSMASK_ECS_DENISE)
-       return 0xFC;
-    return 0xffff;
-}
-STATIC_INLINE uae_u16 DMACONR (void)
-{
-    uae_u16 v;
-    decide_blitter (current_hpos ());
-    v = dmacon | (bltstate == BLT_done ? 0 : 0x4000)
-           | (blt_info.blitzero ? 0x2000 : 0);
-    return v;
-}
-STATIC_INLINE uae_u16 INTENAR (void)
-{
-    return intena;
-}
-uae_u16 INTREQR (void)
-{
-    return intreq;
-}
-STATIC_INLINE uae_u16 ADKCONR (void)
-{
-    return adkcon;
-}
-STATIC_INLINE uae_u16 VPOSR (void)
-{
-    unsigned int csbit = currprefs.ntscmode ? 0x1000 : 0;
-    int vp = (vpos >> 8) & 7;
-#ifdef AGA
-    csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0;
-#else
-    csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0;
-#endif
-    if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       vp &= 1;
-    vp = vp | lof | csbit;
-    return vp;
-}
-static void VPOSW (uae_u16 v)
-{
-#if 0
-    write_log ("vposw %x at %x\n", v, m68k_getpc());
-#endif
-    if (lof != (v & 0x8000))
-       lof_changed = 1;
-    lof = v & 0x8000;
-    if ( (v & 1) && vpos > 0)
-       hack_vpos = vpos;
-}
-
-STATIC_INLINE uae_u16 VHPOSR (void)
-{
-    uae_u16 v = (vpos << 8) | current_hpos ();
-    return v;
-}
-
-STATIC_INLINE void COP1LCH (uae_u16 v) { cop1lc = (cop1lc & 0xffff) | ((uae_u32)v << 16); }
-STATIC_INLINE void COP1LCL (uae_u16 v) { cop1lc = (cop1lc & ~0xffff) | (v & 0xfffe); }
-STATIC_INLINE void COP2LCH (uae_u16 v) { cop2lc = (cop2lc & 0xffff) | ((uae_u32)v << 16); }
-STATIC_INLINE void COP2LCL (uae_u16 v) { cop2lc = (cop2lc & ~0xffff) | (v & 0xfffe); }
-
-static void COPJMP (int num)
-{
-    int was_active = eventtab[ev_copper].active;
-    eventtab[ev_copper].active = 0;
-    if (was_active)
-       events_schedule ();
-
-    cop_state.ignore_next = 0;
-    cop_state.state = COP_read1;
-    cop_state.vpos = vpos;
-    cop_state.hpos = current_hpos () & ~1;
-    cop_state.strobe = num;
-    copper_enabled_thisline = 0;
-
-    if (dmaen (DMA_COPPER)) {
-       copper_enabled_thisline = 1;
-       set_special (SPCFLAG_COPPER);
-    }
-}
-
-STATIC_INLINE void COPCON (uae_u16 a)
-{
-    copcon = a;
-}
-
-static void compute_spcflag_copper (void);
-static void DMACON (int hpos, uae_u16 v)
-{
-    int oldcop, newcop;
-    uae_u16 changed;
-
-    uae_u16 oldcon = dmacon;
-
-    decide_line (hpos);
-    decide_fetch (hpos);
-    decide_blitter (hpos);
-
-    setclr (&dmacon, v);
-    dmacon &= 0x1FFF;
-
-    changed = dmacon ^ oldcon;
-
-    oldcop = (oldcon & DMA_COPPER) && (oldcon & DMA_MASTER);
-    newcop = (dmacon & DMA_COPPER) && (dmacon & DMA_MASTER);
-
-    if (oldcop != newcop) {
-       eventtab[ev_copper].active = 0;
-       if (newcop && !oldcop) {
-           compute_spcflag_copper ();
-       } else if (!newcop) {
-           copper_enabled_thisline = 0;
-           unset_special (SPCFLAG_COPPER);
-       }
-    }
-    if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) {
-       static int count = 0;
-       if (!count) {
-           count = 1;
-           write_log ("warning: program is doing blitpri hacks.\n");
-       }
-       set_special (SPCFLAG_BLTNASTY);
-       decide_blitter (hpos);
-    }
-    if (dmaen (DMA_BLITTER) && bltstate == BLT_init)
-       bltstate = BLT_work;
-    if ((dmacon & (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) != (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) {
-       unset_special (SPCFLAG_BLTNASTY);
-       decide_blitter (hpos);
-    }
-    if (changed & (DMA_MASTER | 0x0f))
-       audio_hsync (0);
-    if (changed & (DMA_MASTER | DMA_BITPLANE)) {
-        ddf_change = vpos;
-       if (dmaen (DMA_BITPLANE))
-           maybe_start_bpl_dma (hpos);
-    }
-           
-    events_schedule();
-}
-
-
-static int intlev_2 (void)
-{
-    uae_u16 imask = intreq & intena;
-    unsigned long cycles = get_cycles ();
-    int c = currprefs.cpu_level >= 2 ? 20 : 4;
-    int i;
-
-    if (!(imask && (intena & 0x4000))) {
-        unset_special (SPCFLAG_INT);
-       return -1;
-    }
-    for (i = 14; i >= 0; i--) {
-       if (imask & (1 << i)) {
-           if (!(irqdelay[i] && (cycles - irqcycles[i]) < c * CYCLE_UNIT)) {
-               irqdelay[i] = 0;
-               if (i == 13 || i == 14)
-                   return 6;
-               else if (i == 11 || i == 12)
-                   return 5;
-               else if (i >= 7 && i <= 10)
-                   return 4;
-               else if (i >= 4 && i <= 6)
-                   return 3;
-               else if (i == 3)
-                   return 2;
-               else
-                   return 1;
-           }
-       }
-    }
-    return -1;
-}
-
-int intlev (void)
-{
-    int il = intlev_2 ();
-    if (il >= 0 && il <= regs.intmask)
-       unset_special (SPCFLAG_INT);
-    return il;
-}
-
-static void doint (void)
-{
-    int i;
-    uae_u16 imask = intreq & intena;
-
-    set_special (SPCFLAG_INT);
-    if (imask && (intena & 0x4000)) {
-       for (i = 0; i < 14; i++) {
-           if ((imask & (1 << i)) && irqdelay[i] == 0) {
-               irqdelay[i] = 1;
-               irqcycles[i] = get_cycles ();
-           }
-       }
-    }
-}
-
-STATIC_INLINE void INTENA (uae_u16 v)
-{
-    setclr (&intena,v);
-#if 0
-    if (v & 0x100)
-       write_log("INTENA %04.4X (%04.4X) %p\n", intena, v, m68k_getpc());
-#endif
-    if (v & 0x8000)
-       doint ();
-}
-
-void INTREQ_0 (uae_u16 v)
-{
-    setclr (&intreq,v);
-    doint ();
-}
-
-void INTREQ (uae_u16 v)
-{
-    INTREQ_0 (v);
-    serial_check_irq ();
-    rethink_cias ();
-#if 0
-    if (v & 0x100)
-       write_log("INTREQ %04.4X (%04.4X) %p\n", intreq, v, m68k_getpc());
-#endif
-}
-
-static void ADKCON (int hpos, uae_u16 v)
-{
-    if (currprefs.produce_sound > 0)
-       update_audio ();
-
-    setclr (&adkcon,v);
-    update_adkmasks ();
-    DISK_update (hpos);
-    if ((v >> 11) & 1)
-       serial_uartbreak ((adkcon >> 11) & 1);
-}
-
-static void dumpsync (void)
-{
-#if 0
-    write_log ("BEAMCON0 = %04.4X VTOTAL=%04.4X HTOTAL=%04.4X\n", new_beamcon0, vtotal, htotal);
-    write_log ("HSSTOP=%04.4X HBSTRT=%04.4X HBSTOP=%04.4X\n", hsstop, hbstrt, hbstop);
-    write_log ("VSSTOP=%04.4X VBSTRT=%04.4X VBSTOP=%04.4X\n", vsstop, vbstrt, vbstop);
-    write_log ("HSSTRT=%04.4X VSSTRT=%04.4X HCENTER=%04.4X\n", hsstrt, vsstrt, hcenter);
-#endif
-}
-
-static void BEAMCON0 (uae_u16 v)
-{
-    if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
-       if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
-           v &= 0x20;
-       if (v != new_beamcon0) {
-            new_beamcon0 = v;
-           if (v & ~0x20)
-               write_log ("warning: %04.4X written to BEAMCON0\n", v);
-       }
-    }
-}
-
-static void varsync (void)
-{
-#ifdef PICASSO96
-    if (p96refresh_active)
-    {
-       extern int p96hack_vpos2;
-       static int p96hack_vpos_old;
-       if (p96hack_vpos_old == p96hack_vpos2) return;
-       vtotal = p96hack_vpos2;
-       p96hack_vpos_old = p96hack_vpos2;
-       hack_vpos = -1;
-       return;
-    }
-#endif
-    if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
-       return;
-    if (!(beamcon0 & 0x80))
-       return;
-    hack_vpos = -1;
-    dumpsync ();
-}
-
-
-static void BPLxPTH (int hpos, uae_u16 v, int num)
-{
-    decide_line (hpos);
-    decide_fetch (hpos);
-    bplpt[num] = (bplpt[num] & 0xffff) | ((uae_u32)v << 16);
-    //write_log("%d:%d:BPL%dPTH %08.8X\n", hpos, vpos, num, v);
-}
-static void BPLxPTL (int hpos, uae_u16 v, int num)
-{
-    decide_line (hpos);
-    decide_fetch (hpos);
-    bplpt[num] = (bplpt[num] & ~0xffff) | (v & 0xfffe);
-    //write_log("%d:%d:BPL%dPTL %08.8X\n", hpos, vpos, num, v);
-}
-
-static void BPLCON0 (int hpos, uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE))
-       v &= ~0x00F1;
-    else if (! (currprefs.chipset_mask & CSMASK_AGA))
-       v &= ~0x00B1;
-
-    if (bplcon0 == v)
-       return;
-
-    ddf_change = vpos;
-    decide_line (hpos);
-    decide_fetch (hpos);
-    decide_blitter (hpos);
-
-    /* HAM change?  */
-    if ((bplcon0 ^ v) & 0x800) {
-       record_color_change (hpos, -1, !! (v & 0x800));
-    }
-    bplcon0 = v;
-
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA) {
-       decide_sprites (hpos);
-       expand_sprres ();
-    }
-#endif
-
-    expand_fmodes ();
-    calcdiw ();
-    estimate_last_fetch_cycle (hpos);
-}
-
-STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v)
-{
-    if (!(currprefs.chipset_mask & CSMASK_AGA))
-       v &= 0xff;
-    if (bplcon1 == v)
-       return;
-    decide_line (hpos);
-    decide_fetch (hpos);
-    bplcon1 = v;
-}
-
-STATIC_INLINE void BPLCON2 (int hpos, uae_u16 v)
-{
-    if (!(currprefs.chipset_mask & CSMASK_AGA))
-       v &= 0x7f;
-    if (bplcon2 == v)
-       return;
-    decide_line (hpos);
-    bplcon2 = v;
-}
-
-#ifdef AGA
-STATIC_INLINE void BPLCON3 (int hpos, uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_AGA))
-       return;
-    if (bplcon3 == v)
-       return;
-    decide_line (hpos);
-    decide_sprites (hpos);
-    bplcon3 = v;
-    expand_sprres ();
-}
-
-STATIC_INLINE void BPLCON4 (int hpos, uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_AGA))
-       return;
-    if (bplcon4 == v)
-       return;
-    decide_line (hpos);
-    bplcon4 = v;
-}
-#endif
-
-static void BPL1MOD (int hpos, uae_u16 v)
-{
-    v &= ~1;
-    if ((uae_s16)bpl1mod == (uae_s16)v)
-       return;
-    decide_line (hpos);
-    decide_fetch (hpos);
-    bpl1mod = v;
-}
-
-static void BPL2MOD (int hpos, uae_u16 v)
-{
-    v &= ~1;
-    if ((uae_s16)bpl2mod == (uae_s16)v)
-       return;
-    decide_line (hpos);
-    decide_fetch (hpos);
-    bpl2mod = v;
-}
-
-STATIC_INLINE void BPL1DAT (int hpos, uae_u16 v)
-{
-    decide_line (hpos);
-    bpl1dat = v;
-
-    maybe_first_bpl1dat (hpos);
-}
-/* We could do as well without those... */
-STATIC_INLINE void BPL2DAT (uae_u16 v) { bpl2dat = v; }
-STATIC_INLINE void BPL3DAT (uae_u16 v) { bpl3dat = v; }
-STATIC_INLINE void BPL4DAT (uae_u16 v) { bpl4dat = v; }
-STATIC_INLINE void BPL5DAT (uae_u16 v) { bpl5dat = v; }
-STATIC_INLINE void BPL6DAT (uae_u16 v) { bpl6dat = v; }
-STATIC_INLINE void BPL7DAT (uae_u16 v) { bpl7dat = v; }
-STATIC_INLINE void BPL8DAT (uae_u16 v) { bpl8dat = v; }
-
-static void DIWSTRT (int hpos, uae_u16 v)
-{
-    if (diwstrt == v && ! diwhigh_written)
-       return;
-    decide_line (hpos);
-    diwhigh_written = 0;
-    diwstrt = v;
-    calcdiw ();
-}
-
-static void DIWSTOP (int hpos, uae_u16 v)
-{
-    if (diwstop == v && ! diwhigh_written)
-       return;
-    decide_line (hpos);
-    diwhigh_written = 0;
-    diwstop = v;
-    calcdiw ();
-}
-
-static void DIWHIGH (int hpos, uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       return;
-    if (diwhigh_written && diwhigh == v)
-       return;
-    decide_line (hpos);
-    diwhigh_written = 1;
-    diwhigh = v;
-    calcdiw ();
-}
-
-static void DDFSTRT (int hpos, uae_u16 v)
-{
-    v &= 0xfe;
-    if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       v &= 0xfc;
-    if (ddfstrt == v)
-       return;
-    ddf_change = vpos;
-    decide_line (hpos);
-    ddfstrt_old = ddfstrt;
-    ddfstrt_old_hpos = hpos;
-    ddfstrt_old_vpos = vpos;
-    ddfstrt = v;
-    calcdiw ();
-    if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) {
-       static int last_warned;
-       last_warned = (last_warned + 1) & 4095;
-       if (last_warned == 0)
-           write_log ("WARNING! Very strange DDF values.\n");
-    }
-}
-
-int test_cnt = 0x80;
-
-static void DDFSTOP (int hpos, uae_u16 v)
-{
-    v &= 0xfe;
-    if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       v &= 0xfc;
-    if (ddfstop == v)
-       return;
-    decide_line (hpos);
-    decide_fetch (hpos);
-    decide_blitter (hpos);
-    ddfstop = v;
-    calcdiw ();
-    if (fetch_state != fetch_not_started)
-       estimate_last_fetch_cycle (hpos);
-    if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) {
-       static int last_warned;
-       if (last_warned == 0)
-           write_log ("WARNING! Very strange DDF values (%x).\n", ddfstop);
-       last_warned = (last_warned + 1) & 4095;
-    }
-}
-
-static void FMODE (uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_AGA))
-       v = 0;
-    ddf_change = vpos;
-    fmode = v;
-    sprite_width = GET_SPRITEWIDTH (fmode);
-    switch (fmode & 3) {
-    case 0:
-       fetchmode = 0;
-       break;
-    case 1:
-    case 2:
-       fetchmode = 1;
-       break;
-    case 3:
-       fetchmode = 2;
-       break;
-    }
-    expand_fmodes ();
-    calcdiw ();
-}
-
-static void BLTADAT (uae_u16 v)
-{
-    maybe_blit (current_hpos(), 0);
-
-    blt_info.bltadat = v;
-}
-/*
- * "Loading data shifts it immediately" says the HRM. Well, that may
- * be true for BLTBDAT, but not for BLTADAT - it appears the A data must be
- * loaded for every word so that AFWM and ALWM can be applied.
- */
-static void BLTBDAT (uae_u16 v)
-{
-    maybe_blit (current_hpos(), 0);
-
-    if (bltcon1 & 2)
-       blt_info.bltbhold = v << (bltcon1 >> 12);
-    else
-       blt_info.bltbhold = v >> (bltcon1 >> 12);
-    blt_info.bltbdat = v;
-}
-static void BLTCDAT (uae_u16 v) { maybe_blit (current_hpos(), 0); blt_info.bltcdat = v; reset_blit (0); }
-
-static void BLTAMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltamod = (uae_s16)(v & 0xFFFE); reset_blit (0); }
-static void BLTBMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltbmod = (uae_s16)(v & 0xFFFE); reset_blit (0); }
-static void BLTCMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltcmod = (uae_s16)(v & 0xFFFE); reset_blit (0); }
-static void BLTDMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltdmod = (uae_s16)(v & 0xFFFE); reset_blit (0); }
-
-static void BLTCON0 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon0 = v; blinea_shift = v >> 12; reset_blit (1); }
-/* The next category is "Most useless hardware register".
- * And the winner is... */
-static void BLTCON0L (uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       return;
-    maybe_blit (current_hpos(), 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
-    reset_blit (1);
-}
-static void BLTCON1 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon1 = v; reset_blit (2); }
-
-static void BLTAFWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltafwm = v; reset_blit (0); }
-static void BLTALWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltalwm = v; reset_blit (0); }
-
-static void BLTAPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & 0xffff) | ((uae_u32)v << 16); }
-static void BLTAPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & ~0xffff) | (v & 0xFFFE); }
-static void BLTBPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & 0xffff) | ((uae_u32)v << 16); }
-static void BLTBPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & ~0xffff) | (v & 0xFFFE); }
-static void BLTCPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & 0xffff) | ((uae_u32)v << 16); }
-static void BLTCPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & ~0xffff) | (v & 0xFFFE); }
-static void BLTDPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & 0xffff) | ((uae_u32)v << 16); }
-static void BLTDPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); }
-
-static void BLTSIZE (uae_u16 v)
-{
-    maybe_blit (current_hpos(), 0);
-
-    blt_info.vblitsize = v >> 6;
-    blt_info.hblitsize = v & 0x3F;
-    if (!blt_info.vblitsize) blt_info.vblitsize = 1024;
-    if (!blt_info.hblitsize) blt_info.hblitsize = 64;
-    do_blitter (current_hpos());
-}
-
-static void BLTSIZV (uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       return;
-    maybe_blit (current_hpos(), 0);
-    blt_info.vblitsize = v & 0x7FFF;
-}
-
-static void BLTSIZH (uae_u16 v)
-{
-    if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       return;
-    maybe_blit (current_hpos(), 0);
-    blt_info.hblitsize = v & 0x7FF;
-    if (!blt_info.vblitsize) blt_info.vblitsize = 32768;
-    if (!blt_info.hblitsize) blt_info.hblitsize = 0x800;
-    do_blitter (current_hpos());
-}
-
-STATIC_INLINE void SPRxCTLPOS (int num)
-{
-    int sprxp;
-    struct sprite *s = &spr[num];
-
-    sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1);
-    /* Quite a bit salad in this register... */
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA) {
-       /* We ignore the SHRES 35ns increment for now; SHRES support doesn't
-          work anyway, so we may as well restrict AGA sprites to a 70ns
-          resolution.  */
-       sprxp <<= 1;
-       sprxp |= (sprctl[num] >> 4) & 1;
-    }
-#endif
-    s->xpos = sprxp;
-    s->vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100);
-    s->vstop = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100);
-    if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
-       s->vstart |= (sprctl[num] << 3) & 0x200;
-       s->vstop |= (sprctl[num] << 4) & 0x200;
-    }
-    if (vpos == s->vstart)
-        s->dmastate = 1;
-    if (vpos == s->vstop)
-        s->dmastate = 0;
-}
-    
-STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos)
-{
-    struct sprite *s = &spr[num];
-    sprctl[num] = v;
-    nr_armed -= s->armed;
-    s->armed = 0;
-    SPRxCTLPOS (num);
-#if SPRITE_DEBUG > 0
-    if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-       write_log ("%d:%d:SPR%dCTL %04.4X VSTRT=%d VSTOP=%d HSTRT=%d DMA=%d ARM=%d COP=%x PC=%x\n",
-           vpos, hpos, num, v, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc());
-    }
-#endif
-
-}
-STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num, int hpos)
-{
-    struct sprite *s = &spr[num];
-    sprpos[num] = v;
-    SPRxCTLPOS (num);
-#if SPRITE_DEBUG > 0
-    if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-        write_log ("%d:%d:SPR%dPOS %04.4X VSTRT=%d VSTOP=%d HSTRT=%d DMA=%d ARM=%d COP=%x PC=%x\n",
-           vpos, hpos, num, v, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc());
-    }
-#endif
-}
-STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num, int hpos)
-{
-    sprdata[num][0] = v;
-#ifdef AGA
-    sprdata[num][1] = v;
-    sprdata[num][2] = v;
-    sprdata[num][3] = v;
-#endif
-    nr_armed += 1 - spr[num].armed;
-    spr[num].armed = 1;
-#if SPRITE_DEBUG > 1
-    if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-        write_log ("%d:%d:SPR%dDATA %04.4X DMA=%d ARM=%d PC=%x\n",
-           vpos, hpos, num, v, spr[num].dmastate, spr[num].armed, m68k_getpc());
-    }
-#endif
-}
-STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num, int hpos)
-{
-    sprdatb[num][0] = v;
-#ifdef AGA
-    sprdatb[num][1] = v;
-    sprdatb[num][2] = v;
-    sprdatb[num][3] = v;
-#endif
-#if SPRITE_DEBUG > 1
-    if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-        write_log ("%d:%d:SPR%dDATB %04.4X DMA=%d ARM=%d PC=%x\n",
-           vpos, hpos, num, v, spr[num].dmastate, spr[num].armed, m68k_getpc());
-    }
-#endif
-}
-static void SPRxDATA (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATA_1 (v, num, hpos); }
-static void SPRxDATB (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATB_1 (v, num, hpos); }
-static void SPRxCTL (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxCTL_1 (v, num, hpos); }
-static void SPRxPOS (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxPOS_1 (v, num, hpos); }
-static void SPRxPTH (int hpos, uae_u16 v, int num)
-{
-    decide_sprites (hpos);
-    spr[num].pt &= 0xffff;
-    spr[num].pt |= (uae_u32)v << 16;
-#if SPRITE_DEBUG > 0
-    if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-        write_log ("%d:%d:SPR%dPTH %08.8X\n", vpos, hpos, num, spr[num].pt);
-    }
-#endif
-}
-static void SPRxPTL (int hpos, uae_u16 v, int num)
-{
-    decide_sprites (hpos);
-    spr[num].pt &= ~0xffff;
-    spr[num].pt |= v;
-#if SPRITE_DEBUG > 0
-     if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-       write_log ("%d:%d:SPR%dPTL %08.8X\n", vpos, hpos, num, spr[num].pt);
-     }
-#endif
-}
-
-static void CLXCON (uae_u16 v)
-{
-    clxcon = v;
-    clxcon_bpl_enable = (v >> 6) & 63;
-    clxcon_bpl_match = v & 63;
-    //write_log("CLXCON: %04.4X PC=%x\n", v, m68k_getpc());
-}
-
-static void CLXCON2 (uae_u16 v)
-{
-    if (!(currprefs.chipset_mask & CSMASK_AGA))
-       return;
-    clxcon2 = v;
-    clxcon_bpl_enable |= v & (0x40|0x80);
-    clxcon_bpl_match |= (v & (0x01|0x02)) << 6;
-    //write_log("CLXCON2: %04.4X\n", v);
-}
-
-static uae_u16 CLXDAT (void)
-{
-    uae_u16 v = clxdat | 0x8000;
-    //write_log("%d:CLXDAT %04.4X PC=%x\n", vpos, v, m68k_getpc());
-    clxdat = 0;
-    return v;
-}
-
-#ifdef AGA
-static uae_u16 COLOR_READ (int num)
-{
-    int cr, cg, cb, colreg;
-    uae_u16 cval;
-
-    if (!(currprefs.chipset_mask & CSMASK_AGA) || !(bplcon2 & 0x0100))
-       return 0xffff;
-
-    colreg = ((bplcon3 >> 13) & 7) * 32 + num;
-    cr = current_colors.color_regs_aga[colreg] >> 16;
-    cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
-    cb = current_colors.color_regs_aga[colreg] & 0xFF;
-    if (bplcon3 & 0x200)
-       cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0);
-    else
-       cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0);
-    return cval;
-}
-#endif
-
-static void COLOR_WRITE (int hpos, uae_u16 v, int num)
-{
-    v &= 0xFFF;
-#ifdef AGA
-    if (currprefs.chipset_mask & CSMASK_AGA) {
-       int r,g,b;
-       int cr,cg,cb;
-       int colreg;
-       uae_u32 cval;
-
-       /* writing is disabled when RDRAM=1 */
-       if (bplcon2 & 0x0100)
-           return;
-
-       colreg = ((bplcon3 >> 13) & 7) * 32 + num;
-       r = (v & 0xF00) >> 8;
-       g = (v & 0xF0) >> 4;
-       b = (v & 0xF) >> 0;
-       cr = current_colors.color_regs_aga[colreg] >> 16;
-       cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
-       cb = current_colors.color_regs_aga[colreg] & 0xFF;
-
-       if (bplcon3 & 0x200) {
-           cr &= 0xF0; cr |= r;
-           cg &= 0xF0; cg |= g;
-           cb &= 0xF0; cb |= b;
-       } else {
-           cr = r + (r << 4);
-           cg = g + (g << 4);
-           cb = b + (b << 4);
-       }
-       cval = (cr << 16) | (cg << 8) | cb;
-       if (cval == current_colors.color_regs_aga[colreg])
-           return;
-
-       /* Call this with the old table still intact. */
-       record_color_change (hpos, colreg, cval);
-       remembered_color_entry = -1;
-       current_colors.color_regs_aga[colreg] = cval;
-       current_colors.acolors[colreg] = CONVERT_RGB (cval);
-   } else {
-#endif
-       if (current_colors.color_regs_ecs[num] == v)
-           return;
-       /* Call this with the old table still intact. */
-       record_color_change (hpos, num, v);
-       remembered_color_entry = -1;
-       current_colors.color_regs_ecs[num] = v;
-       current_colors.acolors[num] = xcolors[v];
-#ifdef AGA
-    }
-#endif
-}
-
-/* The copper code.  The biggest nightmare in the whole emulator.
-
-   Alright.  The current theory:
-   1. Copper moves happen 2 cycles after state READ2 is reached.
-      It can't happen immediately when we reach READ2, because the
-      data needs time to get back from the bus.  An additional 2
-      cycles are needed for non-Agnus registers, to take into account
-      the delay for moving data from chip to chip.
-   2. As stated in the HRM, a WAIT really does need an extra cycle
-      to wake up.  This is implemented by _not_ falling through from
-      a successful wait to READ1, but by starting the next cycle.
-      (Note: the extra cycle for the WAIT apparently really needs a
-      free cycle; i.e. contention with the bitplane fetch can slow
-      it down).
-   3. Apparently, to compensate for the extra wake up cycle, a WAIT
-      will use the _incremented_ horizontal position, so the WAIT
-      cycle normally finishes two clocks earlier than the position
-      it was waiting for.  The extra cycle then takes us to the
-      position that was waited for.
-      If the earlier cycle is busy with a bitplane, things change a bit.
-      E.g., waiting for position 0x50 in a 6 plane display: In cycle
-      0x4e, we fetch BPL5, so the wait wakes up in 0x50, the extra cycle
-      takes us to 0x54 (since 0x52 is busy), then we have READ1/READ2,
-      and the next register write is at 0x5c.
-   4. The last cycle in a line is not usable for the copper.
-   5. A 4 cycle delay also applies to the WAIT instruction.  This means
-      that the second of two back-to-back WAITs (or a WAIT whose
-      condition is immediately true) takes 8 cycles.
-   6. This also applies to a SKIP instruction.  The copper does not
-      fetch the next instruction while waiting for the second word of
-      a WAIT or a SKIP to arrive.
-   7. A SKIP also seems to need an unexplained additional two cycles
-      after its second word arrives; this is _not_ a memory cycle (I
-      think, the documentation is pretty clear on this).
-   8. Two additional cycles are inserted when writing to COPJMP1/2.  */
-
-/* Determine which cycles are available for the copper in a display
- * with a agiven number of planes.  */
-
-int is_bitplane_dma (int hpos)
-{
-    if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft)
-       return 0;
-    if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright)
-       || hpos >= estimated_last_fetch_cycle)
-       return 0;
-    return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
-}
-
-STATIC_INLINE int is_bitplane_dma_inline (int hpos)
-{
-    if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft)
-       return 0;
-    if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright)
-       || hpos >= estimated_last_fetch_cycle)
-       return 0;
-    return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
-}
-
-STATIC_INLINE int copper_cant_read (int hpos)
-{
-    if (hpos + 1 >= maxhpos)
-       return 1;
-    return is_bitplane_dma_inline (hpos);
-}
-
-STATIC_INLINE int dangerous_reg (int reg)
-{
-    /* Safe:
-     * Bitplane pointers, control registers, modulos and data.
-     * Sprite pointers, control registers, and data.
-     * Color registers.  */
-    if (reg >= 0xE0 && reg < 0x1C0)
-       return 0;
-    return 1;
-}
-
-#define FAST_COPPER 1
-
-/* The future, Conan?
-   We try to look ahead in the copper list to avoid doing continuous calls
-   to updat_copper (which is what happens when SPCFLAG_COPPER is set).  If
-   we find that the same effect can be achieved by setting a delayed event
-   and then doing multiple copper insns in one batch, we can get a massive
-   speedup.
-
-   We don't try to be precise here.  All copper reads take exactly 2 cycles,
-   the effect of bitplane contention is ignored.  Trying to get it exactly
-   right would be much more complex and as such carry a huge risk of getting
-   it subtly wrong; and it would also be more expensive - we want this code
-   to be fast.  */
-static void predict_copper (void)
-{
-    uaecptr ip = cop_state.ip;
-    unsigned int c_hpos = cop_state.hpos;
-    enum copper_states state = cop_state.state;
-    unsigned int w1, w2, cycle_count;
-
-    switch (state) {
-    case COP_read1_wr_in2:
-    case COP_read2_wr_in2:
-    case COP_read1_wr_in4:
-       if (dangerous_reg (cop_state.saved_i1))
-           return;
-       state = state == COP_read2_wr_in2 ? COP_read2 : COP_read1;
-       break;
-
-    case COP_read1_in2:
-       c_hpos += 2;
-       state = COP_read1;
-       break;
-
-    case COP_stop:
-    case COP_bltwait:
-    case COP_wait1:
-    case COP_skip_in4:
-    case COP_skip_in2:
-    case COP_skip1:
-    case COP_strobe_delay:
-       return;
-
-    case COP_wait_in4:
-       c_hpos += 2;
-       /* fallthrough */
-    case COP_wait_in2:
-       c_hpos += 2;
-       /* fallthrough */
-    case COP_wait:
-       state = COP_wait;
-       break;
-
-    default:
-       break;
-    }
-
-    /* Only needed for COP_wait, but let's shut up the compiler.  */
-    w1 = cop_state.saved_i1;
-    w2 = cop_state.saved_i2;
-    cop_state.first_sync = c_hpos;
-    cop_state.regtypes_modified = REGTYPE_FORCE;
-
-    /* Get this case out of the way, so that the loop below only has to deal
-       with read1 and wait.  */
-    if (state == COP_read2) {
-       w1 = cop_state.i1;
-       if (w1 & 1) {
-           w2 = chipmem_wget (ip);
-           if (w2 & 1)
-               goto done;
-           state = COP_wait;
-           c_hpos += 4;
-       } else if (dangerous_reg (w1)) {
-           c_hpos += 4;
-           goto done;
-       } else {
-           cop_state.regtypes_modified |= regtypes[w1 & 0x1FE];
-           state = COP_read1;
-           c_hpos += 2;
-       }
-       ip += 2;        
-    }
-
-    while (c_hpos + 1 < maxhpos) {
-       if (state == COP_read1) {
-           w1 = chipmem_wget (ip);
-           if (w1 & 1) {
-               w2 = chipmem_wget (ip + 2);
-               if (w2 & 1)
-                   break;
-               state = COP_wait;
-               c_hpos += 6;
-           } else if (dangerous_reg (w1)) {
-               c_hpos += 6;
-               break;
-           } else {
-               cop_state.regtypes_modified |= regtypes[w1 & 0x1FE];
-               c_hpos += 4;
-           }
-           ip += 4;
-       } else if (state == COP_wait) {
-           if ((w2 & 0xFE) != 0xFE)
-               break;
-           else {
-               unsigned int vcmp = (w1 & (w2 | 0x8000)) >> 8;
-               unsigned int hcmp = (w1 & 0xFE);
-
-               unsigned int vp = vpos & (((w2 >> 8) & 0x7F) | 0x80);
-               if (vp < vcmp) {
-                   /* Whee.  We can wait until the end of the line!  */
-                   c_hpos = maxhpos;
-               } else if (vp > vcmp || hcmp <= c_hpos) {
-                   state = COP_read1;
-                   /* minimum wakeup time */
-                   c_hpos += 2;
-               } else {
-                   state = COP_read1;
-                   c_hpos = hcmp;
-               }
-               /* If this is the current instruction, remember that we don't
-                  need to sync CPU and copper anytime soon.  */
-               if (cop_state.ip == ip) {
-                   cop_state.first_sync = c_hpos;
-               }
-           }
-       } else
-           uae_abort ("predict copper %d", state);
-    }
-
-  done:
-    cycle_count = c_hpos - cop_state.hpos;
-    if (cycle_count >= 8) {
-       unset_special (SPCFLAG_COPPER);
-       eventtab[ev_copper].active = 1;
-       eventtab[ev_copper].oldcycles = get_cycles ();
-       eventtab[ev_copper].evtime = get_cycles () + cycle_count * CYCLE_UNIT;
-       events_schedule ();
-    }
-}
-
-static int test_copper_dangerous (unsigned int address)
-{
-    if ((address & 0x1fe) < (copcon & 2 ? ((currprefs.chipset_mask & CSMASK_AGA) ? 0 : 0x40u) : 0x80u)) {
-       cop_state.state = COP_stop;     
-       copper_enabled_thisline = 0;
-       unset_special (SPCFLAG_COPPER);
-       return 1;
-    }
-    return 0;
-}
-
-static void perform_copper_write (int old_hpos)
-{
-    unsigned int address = cop_state.saved_i1 & 0x1FE;
-
-    record_copper (cop_state.saved_ip - 4, old_hpos, vpos);
-
-    if (test_copper_dangerous (address))
-       return;
-    if (address == 0x88) {
-       cop_state.ip = cop1lc;
-       cop_state.state = COP_strobe_delay;
-    } else if (address == 0x8A) {
-       cop_state.ip = cop2lc;
-       cop_state.state = COP_strobe_delay;
-    } else
-       custom_wput_1 (old_hpos, cop_state.saved_i1, cop_state.saved_i2, 0);
-}
-
-static int isagnus[]= {
-    1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 27 0x40 - 0x74 */
-    0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 21 */
-    1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0, /* 32 0xa0 - 0xde
-    /* BPLxPTH/BPLxPTL */
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
-    0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, /* 16 */
-    /* SPRxPTH/SPRxPTL */
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
-    /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    /* COLORxx */
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    /* RESERVED */
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-
-static void dump_copper (char *error, int until_hpos)
-{
-    write_log("%s: vpos=%d until_hpos=%d\n",
-       error, vpos, until_hpos);
-    write_log("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04.4X ci2=%04.4X\n",
-       cop_state.vcmp,cop_state.hcmp,cop_state.hpos,cop_state.vpos,cop_state.saved_i1,cop_state.saved_i2);
-    write_log("cstate=%d ip=%08.8X ev_copper=%d\n",
-       cop_state.state,cop_state.ip,eventtab[ev_copper].active);
-}
-
-static void update_copper (int until_hpos)
-{
-    int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80);    
-    int c_hpos = cop_state.hpos;
-
-    if (eventtab[ev_copper].active) {
-       static int warned;
-       if (!warned) {
-           dump_copper ("error1",until_hpos);
-           warned = 1;
-       }
-       eventtab[ev_copper].active = 0;
-       return;
-       uae_abort ("update_copper1");
-    }
-
-    if (cop_state.state == COP_wait && vp < cop_state.vcmp) {
-       static int warned;
-       if (!warned) {
-           dump_copper ("error2",until_hpos);
-           warned = 1;
-       }
-       copper_enabled_thisline = 0;
-       return;
-       uae_abort ("update_copper2");
-    }
-    
-    until_hpos &= ~1;
-
-    if (until_hpos > (maxhpos & ~1))
-       until_hpos = maxhpos & ~1;
-
-    until_hpos += 2;
-    for (;;) {
-       int old_hpos = c_hpos;
-       int hp;
-
-       if (c_hpos >= until_hpos)
-           break;
-
-       /* So we know about the fetch state.  */
-       decide_line (c_hpos);
-       
-       switch (cop_state.state) {
-       case COP_read1_in2:
-           cop_state.state = COP_read1;
-           break;
-       case COP_read1_wr_in2:
-           cop_state.state = COP_read1;
-           perform_copper_write (old_hpos);
-           /* That could have turned off the copper.  */
-           if (! copper_enabled_thisline)
-               goto out;
-
-           break;
-       case COP_read1_wr_in4:
-           cop_state.state = COP_read1_wr_in2;
-           break;
-       case COP_read2_wr_in2:
-           cop_state.state = COP_read2;
-           perform_copper_write (old_hpos);
-           /* That could have turned off the copper.  */
-           if (! copper_enabled_thisline)
-               goto out;
-
-           break;
-       case COP_wait_in2:
-           cop_state.state = COP_wait1;
-           break;
-       case COP_wait_in4:
-           cop_state.state = COP_wait_in2;
-           break;
-       case COP_skip_in2:
-           cop_state.state = COP_skip1;
-           break;
-       case COP_skip_in4:
-           cop_state.state = COP_skip_in2;
-           break;
-        case COP_strobe_delay:
-           cop_state.state = COP_read1;
-           break;
-
-       default:
-           break;
-       }
-
-       c_hpos += 2;
-#if 0
-        if (copper_cant_read (old_hpos))
-           continue;
-#endif
-        if (cop_state.strobe) {
-           cop_state.ip = cop_state.strobe == 1 ? cop1lc : cop2lc;
-           cop_state.strobe = 0;
-       }
-
-       switch (cop_state.state) {
-
-       case COP_read1_wr_in4:
-           uae_abort ("COP_read1_wr_in4");
-
-       case COP_read1_wr_in2:
-       case COP_read1:
-           if (copper_cant_read (old_hpos))
-               continue;
-           cop_state.i1 = chipmem_wget (cop_state.ip);
-#ifdef CPUEMU_6
-           cycle_line[old_hpos] |= CYCLE_COPPER;
-#endif
-           cop_state.ip += 2;
-           cop_state.state = cop_state.state == COP_read1 ? COP_read2 : COP_read2_wr_in2;
-           break;
-
-       case COP_read2_wr_in2:
-           uae_abort ("read2_wr_in2");
-
-       case COP_read2:
-           if (copper_cant_read (old_hpos))
-               continue;
-           cop_state.i2 = chipmem_wget (cop_state.ip);
-#ifdef CPUEMU_6
-           cycle_line[old_hpos] |= CYCLE_COPPER;
-#endif
-           cop_state.ip += 2;
-           if (cop_state.ignore_next) {
-               cop_state.ignore_next = 0;
-               cop_state.state = COP_read1;
-               break;
-           }
-
-           cop_state.saved_i1 = cop_state.i1;
-           cop_state.saved_i2 = cop_state.i2;
-           cop_state.saved_ip = cop_state.ip;
-
-           if (cop_state.i1 & 1) {
-               if (cop_state.i2 & 1)
-                   cop_state.state = COP_skip_in4;
-               else
-                   cop_state.state = COP_wait_in4;
-           } else {
-               unsigned int reg = cop_state.i1 & 0x1FE;
-               cop_state.state = isagnus[reg >> 1] ? COP_read1_wr_in2 : COP_read1_wr_in4;
-           }
-           break;
-
-       case COP_wait1:
-           /* There's a nasty case here.  As stated in the "Theory" comment above, we
-              test against the incremented copper position.  I believe this means that
-              we have to increment the _vertical_ position at the last cycle in the line,
-              and set the horizontal position to 0.
-              Normally, this isn't going to make a difference, since we consider these
-              last cycles unavailable for the copper, so waking up in the last cycle has
-              the same effect as waking up at the start of the line.  However, there is
-              one possible problem:  If we're at 0xFFE0, any wait for an earlier position
-              must _not_ complete (since, in effect, the current position will be back
-              at 0/0).  This can be seen in the Superfrog copper list.
-              Things get monstrously complicated if we try to handle this "properly" by
-              incrementing vpos and setting c_hpos to 0.  Especially the various speedup
-              hacks really assume that vpos remains constant during one line.  Hence,
-              this hack: defer the entire decision until the next line if necessary.  */
-           if (c_hpos >= (maxhpos & ~1))
-               break;
-
-           cop_state.state = COP_wait;
-
-           cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
-           cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE);
-
-           vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80);
-           if (cop_state.saved_i1 == 0xFFFF && cop_state.saved_i2 == 0xFFFE) {
-               cop_state.state = COP_stop;
-               copper_enabled_thisline = 0;
-               unset_special (SPCFLAG_COPPER);
-               goto out;
-           }
-           if (vp < cop_state.vcmp) {
-               copper_enabled_thisline = 0;
-               unset_special (SPCFLAG_COPPER);
-               goto out;
-           }
-
-           /* fall through */
-       case COP_wait:
-           if (vp < cop_state.vcmp)
-               uae_abort ("vp < cop_state.vcmp");
-           if (copper_cant_read (old_hpos))
-               continue;
-
-           hp = c_hpos & (cop_state.saved_i2 & 0xFE);
-           if (vp == cop_state.vcmp && hp < cop_state.hcmp) {
-               /* Position not reached yet.  */
-               if (currprefs.fast_copper && FAST_COPPER && (cop_state.saved_i2 & 0xFE) == 0xFE) {
-                   int wait_finish = cop_state.hcmp - 2;
-                   /* This will leave c_hpos untouched if it's equal to wait_finish.  */
-                   if (wait_finish < c_hpos)
-                       uae_abort ("wait_finish < c_hpos");
-                   else if (wait_finish <= until_hpos) {
-                       c_hpos = wait_finish;
-                   } else
-                       c_hpos = until_hpos;
-               }             
-               break;
-           }
-
-           /* Now we know that the comparisons were successful.  We might still
-              have to wait for the blitter though.  */
-           if ((cop_state.saved_i2 & 0x8000) == 0 && (DMACONR() & 0x4000)) {
-               /* We need to wait for the blitter.  */
-               cop_state.state = COP_bltwait;
-               copper_enabled_thisline = 0;
-               unset_special (SPCFLAG_COPPER);
-               goto out;
-           }
-
-           record_copper (cop_state.ip - 4, old_hpos, vpos);
-
-           cop_state.state = COP_read1;
-           break;
-
-       case COP_skip1:
-       {
-           static int skipped_before;
-           unsigned int vcmp, hcmp, vp1, hp1;
-
-           if (! skipped_before) {
-               skipped_before = 1;
-               write_log ("Program uses Copper SKIP instruction.\n");
-           }
-
-           if (c_hpos >= (maxhpos & ~1))
-               break;
-
-           vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
-           hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE);
-           vp1 = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80);
-           hp1 = c_hpos & (cop_state.saved_i2 & 0xFE);
-
-           if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp))
-               && ((cop_state.saved_i2 & 0x8000) != 0 || ! (DMACONR() & 0x4000)))
-               cop_state.ignore_next = 1;
-           if (chipmem_wget (cop_state.ip) & 1) { /* FIXME: HACK!!! */
-               /* copper never skips if following instruction is WAIT or another SKIP... */
-               cop_state.ignore_next = 0;
-           }
-
-           cop_state.state = COP_read1;
-
-           if (cop_state.ignore_next && (chipmem_wget (cop_state.ip) & 1) == 0) {
-               /* another undocumented copper feature:
-                  copper stops if skipped instruction is MOVE to dangerous register...
-               */
-               test_copper_dangerous (chipmem_wget(cop_state.ip));
-           }
-
-           record_copper (cop_state.ip - 4, old_hpos, vpos);
-
-           break;
-       }
-       default:
-           break;
-       }
-    }
-
-  out:
-    cop_state.hpos = c_hpos;
-
-    /* The test against maxhpos also prevents us from calling predict_copper
-       when we are being called from hsync_handler, which would not only be
-       stupid, but actively harmful.  */
-    if (currprefs.fast_copper && FAST_COPPER && (regs.spcflags & SPCFLAG_COPPER) && c_hpos + 8 < maxhpos)
-       predict_copper ();
-}
-
-static void compute_spcflag_copper (void)
-{
-    copper_enabled_thisline = 0;
-    unset_special (SPCFLAG_COPPER);
-    if (! dmaen (DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_bltwait)
-       return;
-
-    if (cop_state.state == COP_wait) {
-       int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80);
-
-       if (vp < cop_state.vcmp)
-           return;
-    }
-    copper_enabled_thisline = 1;
-
-    if (currprefs.fast_copper && FAST_COPPER)
-       predict_copper ();
-
-    if (! eventtab[ev_copper].active)
-       set_special (SPCFLAG_COPPER);
-}
-
-static void copper_handler (void)
-{
-    /* This will take effect immediately, within the same cycle.  */
-    set_special (SPCFLAG_COPPER);
-
-    if (! copper_enabled_thisline)
-       uae_abort ("copper_handler");
-
-    eventtab[ev_copper].active = 0;
-}
-
-void blitter_done_notify (void)
-{
-    if (cop_state.state != COP_bltwait)
-       return;
-
-    cop_state.hpos = current_hpos () & ~1;
-    cop_state.vpos = vpos;
-    cop_state.state = COP_wait;
-    compute_spcflag_copper ();
-}
-
-void do_copper (void)
-{
-    int hpos = current_hpos ();
-    update_copper (hpos);
-}
-
-/* ADDR is the address that is going to be read/written; this access is
-   the reason why we want to update the copper.  This function is also
-   used from hsync_handler to finish up the line; for this case, we check
-   hpos against maxhpos.  */
-STATIC_INLINE void sync_copper_with_cpu (int hpos, int do_schedule, unsigned int addr)
-{
-    /* Need to let the copper advance to the current position.  */
-    if (eventtab[ev_copper].active) {
-       if (hpos != maxhpos) {
-           /* There might be reasons why we don't actually need to bother
-              updating the copper.  */
-           if (hpos < cop_state.first_sync)
-               return;
-
-           if ((cop_state.regtypes_modified & regtypes[addr & 0x1FE]) == 0)
-               return;
-       }
-
-       eventtab[ev_copper].active = 0;
-       if (do_schedule)
-           events_schedule ();
-       set_special (SPCFLAG_COPPER);
-    }
-    if (copper_enabled_thisline)
-       update_copper (hpos);
-}
-
-STATIC_INLINE uae_u16 sprite_fetch (struct sprite *s, int dma, int hpos)
-{
-    uae_u16 data = last_custom_value;
-    if (dma) {
-        data = last_custom_value = chipmem_wget (s->pt);
-#ifdef CPUEMU_6
-       cycle_line[hpos] |= CYCLE_SPRITE;
-#endif
-    }
-    s->pt += 2;
-    return data;
-}
-
-STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos)
-{
-    struct sprite *s = &spr[num];
-    int dma, posctl = 0;
-    uae_u16 data;
-
-    if (vpos == s->vstart) {
-        s->dmastate = 1;
-#if SPRITE_DEBUG > 0
-       write_log ("%d:SPR%d START\n", vpos, num);
-#endif
-    }
-    if (vpos == s->vstop || vpos == sprite_vblank_endline) {
-        s->dmastate = 0;
-#if SPRITE_DEBUG > 0
-       write_log ("%d:SPR%d STOP\n", vpos, num);
-#endif
-    }
-    if (!dmaen (DMA_SPRITE))
-       return;
-    dma = hpos < plfstrt || diwstate != DIW_waiting_stop || !dmaen (DMA_BITPLANE);
-    if (vpos == s->vstop || vpos == sprite_vblank_endline) {
-       s->dmastate = 0;
-       posctl = 1;
-        if (dma) {
-           data = sprite_fetch (s, dma, hpos);
-           s->pt += (sprite_width >> 3) - 2;
-       } else {
-            data = cycle == 0 ? sprpos[num] : sprctl[num];
-       }
-#if SPRITE_DEBUG > 1
-        if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-           write_log ("dma:");
-       }
-#endif
-        if (cycle == 0)
-           SPRxPOS_1 (data, num, hpos);
-       else
-           SPRxCTL_1 (data, num, hpos);
-    }
-    if (s->dmastate && !posctl) {
-       uae_u16 data = sprite_fetch (s, dma, hpos);
-        /* Hack for X mouse auto-calibration */
-        if (num == 0 && cycle == 0)
-            mousehack_handle (sprctl[0], sprpos[0]);
-#if SPRITE_DEBUG > 1
-        if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) {
-           write_log ("dma:");
-       }
-#endif
-        if (cycle == 0)
-            SPRxDATA_1 (dma ? data : sprdata[num][0], num, hpos);
-        else
-            SPRxDATB_1 (dma ? data : sprdatb[num][0], num, hpos);
-#ifdef AGA
-        switch (sprite_width)
-            {
-            case 64:
-           {
-               uae_u16 data32 = sprite_fetch (s, dma, hpos);
-               uae_u16 data641 = sprite_fetch (s, dma, hpos);
-               uae_u16 data642 = sprite_fetch (s, dma, hpos);
-               if (dma) {
-                   if (cycle == 0) {
-                       sprdata[num][3] = data642;
-                       sprdata[num][2] = data641;
-                       sprdata[num][1] = data32;
-                   } else {
-                       sprdatb[num][3] = data642;
-                       sprdatb[num][2] = data641;
-                       sprdatb[num][1] = data32;
-                   }
-               }
-           }
-            break;
-            case 32:
-           {   
-               uae_u16 data32 = sprite_fetch (s, dma, hpos);
-               if (dma) {
-                   if (cycle == 0)
-                       sprdata[num][1] = data32;
-                   else
-                       sprdatb[num][1] = data32;
-               }
-           }
-           break;
-       }
-#endif
-    }
-}
-
-static void do_sprites (int hpos)
-{
-    int maxspr, minspr;
-    int i;
-
-    /* I don't know whether this is right. Some programs write the sprite pointers
-     * directly at the start of the copper list. With the test against currvp, the
-     * first two words of data are read on the second line in the frame. The problem
-     * occurs when the program jumps to another copperlist a few lines further down
-     * which _also_ writes the sprite pointer registers. This means that a) writing
-     * to the sprite pointers sets the state to SPR_restart; or b) that sprite DMA
-     * is disabled until the end of the vertical blanking interval. The HRM
-     * isn't clear - it says that the vertical sprite position can be set to any
-     * value, but this wouldn't be the first mistake... */
-    /* Update: I modified one of the programs to write the sprite pointers the
-     * second time only _after_ the VBlank interval, and it showed the same behaviour
-     * as it did unmodified under UAE with the above check. This indicates that the
-     * solution below is correct. */
-    /* Another update: seems like we have to use the NTSC value here (see Sanity Turmoil
-     * demo).  */
-    /* Maximum for Sanity Turmoil: 27.
-       Minimum for Sanity Arte: 22.  */
-    if (vpos < sprite_vblank_endline)
-       return;
-
-#ifndef CUSTOM_SIMPLE
-    maxspr = hpos;
-    minspr = last_sprite_hpos;
-
-    if (minspr >= SPR0_HPOS + MAX_SPRITES * 4 || maxspr < SPR0_HPOS)
-       return;
-
-    if (maxspr > SPR0_HPOS + MAX_SPRITES * 4)
-       maxspr = SPR0_HPOS + MAX_SPRITES * 4;
-    if (minspr < SPR0_HPOS)
-        minspr = SPR0_HPOS;
-
-    for (i = minspr; i < maxspr; i++) {
-       int cycle = -1;
-        switch ((i - SPR0_HPOS) & 3)
-           {
-           case 0:
-           cycle = 0;
-           break;
-           case 2:
-           cycle = 1;
-           break;
-       }
-       if (cycle >= 0)
-           do_sprites_1 ((i - SPR0_HPOS) / 4, cycle, i);
-    }
-    last_sprite_hpos = hpos;
-#else
-    for (i = 0; i < MAX_SPRITES * 2; i++)
-       do_sprites_1 (i / 2, i & 1, 0);
-#endif
-}
-
-static void init_sprites (void)
-{
-    memset (sprpos, 0, sizeof sprpos);
-    memset (sprctl, 0, sizeof sprctl);
-}
-
-static void adjust_array_sizes (void)
-{
-#ifdef OS_WITHOUT_MEMORY_MANAGEMENT
-    if (delta_sprite_entry) {
-       void *p1,*p2;
-       int mcc = max_sprite_entry + 50 + delta_sprite_entry;
-       delta_sprite_entry = 0;
-       p1 = realloc (sprite_entries[0], mcc * sizeof (struct sprite_entry));
-       p2 = realloc (sprite_entries[1], mcc * sizeof (struct sprite_entry));
-       if (p1) sprite_entries[0] = p1;
-       if (p2) sprite_entries[1] = p2;
-       if (p1 && p2) {
-           write_log ("new max_sprite_entry=%d\n",mcc);
-           max_sprite_entry = mcc;
-       }
-    }
-    if (delta_color_change) {
-       void *p1,*p2;
-       int mcc = max_color_change + 200 + delta_color_change;
-       delta_color_change = 0;
-       p1 = realloc (color_changes[0], mcc * sizeof (struct color_change));
-       p2 = realloc (color_changes[1], mcc * sizeof (struct color_change));
-       if (p1) color_changes[0] = p1;
-       if (p2) color_changes[1] = p2;
-       if (p1 && p2) {
-           write_log ("new max_color_change=%d\n",mcc);
-           max_color_change = mcc;
-       }
-    }
-#endif
-}
-
-static void init_hardware_frame (void)
-{
-    next_lineno = 0;
-    nextline_how = nln_normal;
-    diwstate = DIW_waiting_start;
-    hdiwstate = DIW_waiting_start;
-    ddfstate = DIW_waiting_start;
-}
-
-void init_hardware_for_drawing_frame (void)
-{
-    adjust_array_sizes ();
-
-    /* Avoid this code in the first frame after a customreset.  */
-    if (prev_sprite_entries) {
-       int first_pixel = prev_sprite_entries[0].first_pixel;
-       int npixels = prev_sprite_entries[prev_next_sprite_entry].first_pixel - first_pixel;
-       memset (spixels + first_pixel, 0, npixels * sizeof *spixels);
-       memset (spixstate.bytes + first_pixel, 0, npixels * sizeof *spixstate.bytes);
-    }
-    prev_next_sprite_entry = next_sprite_entry;
-
-    next_color_change = 0;
-    next_sprite_entry = 0;
-    next_color_entry = 0;
-    remembered_color_entry = -1;
-
-    prev_sprite_entries = sprite_entries[current_change_set];
-    curr_sprite_entries = sprite_entries[current_change_set ^ 1];
-    prev_color_changes = color_changes[current_change_set];
-    curr_color_changes = color_changes[current_change_set ^ 1];
-    prev_color_tables = color_tables[current_change_set];
-    curr_color_tables = color_tables[current_change_set ^ 1];
-
-    prev_drawinfo = line_drawinfo[current_change_set];
-    curr_drawinfo = line_drawinfo[current_change_set ^ 1];
-    current_change_set ^= 1;
-
-    color_src_match = color_dest_match = -1;
-
-    /* Use both halves of the array in alternating fashion.  */
-    curr_sprite_entries[0].first_pixel = current_change_set * MAX_SPR_PIXELS;
-    next_sprite_forced = 1;
-}
-
-static void do_savestate(void);
-
-static int rpt_vsync (void)
-{
-    int v = read_processor_time () - vsyncmintime;
-    if (v > (int)syncbase || v < -((int)syncbase)) {
-       vsyncmintime = read_processor_time();
-       v = 0;
-    }
-    return v;
-}
-       
-static void framewait (void)
-{
-    frame_time_t curr_time;
-    int start;
-
-    for (;;) {
-        double v = rpt_vsync () / (syncbase / 1000.0);
-       if (v >= -4)
-           break;
-        sleep_millis_busy (1);
-    }
-    start = read_processor_time();
-    do {
-        curr_time = read_processor_time ();
-    } while (rpt_vsync () < 0);
-    vsyncmintime = curr_time + vsynctime;
-    idletime += read_processor_time() - start;
-}
-
-static int frametime2;
-
-void fpscounter_reset (void)
-{
-    timeframes = 0;
-    frametime2 = 0;
-    bogusframe = 2;
-    lastframetime = read_processor_time ();
-    idletime = 0;
-}
-
-static void fpscounter (void)
-{
-    int now, last;
-    
-    now = read_processor_time ();
-    last = now - lastframetime;
-    lastframetime = now;
-
-    if (bogusframe)
-       return;
-
-    frametime += last;
-    frametime2 += last;
-    timeframes++;
-    if ((timeframes & 31) == 0) {
-       double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * 32.0));
-       int fps = frametime2 == 0 ? 0 : syncbase * 32 / (frametime2 / 10);
-       if (fps > 9999)
-               fps = 9999;
-       if (idle < 0)
-           idle = 0;
-       if (idle > 100 * 10)
-           idle = 100 * 10;
-       if (fake_vblank_hz * 10 > fps) {
-           double mult = (double)fake_vblank_hz * 10.0 / fps;
-           idle *= mult;
-       }
-       if (turbo_emulation && idle < 100 * 10)
-           idle = 100 * 10;
-       gui_fps (fps, (int)idle);
-       frametime2 = 0;
-       idletime = 0;
-    }
-}
-
-static void vsync_handler (void)
-{
-    fpscounter ();
-
-    if ((!currprefs.gfx_vsync || !currprefs.gfx_afullscreen)
-#ifdef AVIOUTPUT
-       && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled)
-#endif
-       ) {
-#ifdef JIT
-       if (!compiled_code) {
-#endif
-           if (currprefs.m68k_speed == -1) {
-               frame_time_t curr_time = read_processor_time ();
-               vsyncmintime += vsynctime;
-               /* @@@ Mathias? How do you think we should do this? */
-               /* If we are too far behind, or we just did a reset, adjust the
-                * needed time. */
-               if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset)
-                   vsyncmintime = curr_time + vsynctime;
-               rpt_did_reset = 0;
-           } else if (rpt_available) {
-               framewait ();
-           }
-#ifdef JIT
-       } else {
-           if (rpt_available && currprefs.m68k_speed == 0) {
-               framewait ();
-           }
-       }
-#endif
-    }
-
-    if (bogusframe > 0)
-       bogusframe--;
-
-    handle_events ();
-
-    INTREQ (0x8020);
-    if (bplcon0 & 4)
-       lof ^= 0x8000;
-
-#ifdef PICASSO96
-    /* And now let's update the Picasso palette, if required */
-    DX_SetPalette_vsync();
-    if (picasso_on)
-       picasso_handle_vsync ();
-#endif
-   vsync_handle_redraw (lof, lof_changed);
-
-    if (quit_program > 0) {
-       /* prevent possible infinite loop at wait_cycles().. */
-       framecnt = 0;
-        reset_decisions ();
-       return;
-    }
-
-    {
-       static int cnt = 0;
-       if (cnt == 0) {
-           /* resolution_check_change (); */
-           DISK_check_change ();
-           cnt = 5;
-       }
-       cnt--;
-    }
-
-    /* Start a new set of copper records.  */
-    curr_cop_set ^= 1;
-    nr_cop_records[curr_cop_set] = 0;
-
-    /* For now, let's only allow this to change at vsync time.  It gets too
-     * hairy otherwise.  */
-    if ((beamcon0 & (0x20|0x80)) != (new_beamcon0 & (0x20|0x80)) || hack_vpos)
-       init_hz ();
-
-    lof_changed = 0;
-
-    eventtab[ev_copper].active = 0;
-    COPJMP (1);
-
-    init_hardware_frame ();
-
-    if (ievent_alive > 0)
-       ievent_alive--;
-    if (timehack_alive > 0)
-       timehack_alive--;
-    inputdevice_vsync ();
-
-}
-
-#ifdef JIT
-
-#define N_LINES 8
-
-static __inline__ int trigger_frh(int v)
-{
-    return (v & (N_LINES - 1)) == 0;
-}
-
-extern int gonebad;
-
-static long int diff32(frame_time_t x, frame_time_t y)
-{
-    return (long int)(x-y);
-}
-static void frh_handler(void)
-{
-    if (currprefs.m68k_speed == -1) {
-       frame_time_t curr_time = read_processor_time ();
-       vsyncmintime += vsynctime * N_LINES / maxvpos;
-       /* @@@ Mathias? How do you think we should do this? */
-       /* If we are too far behind, or we just did a reset, adjust the
-        * needed time. */
-       if (rpt_did_reset) {
-           vsyncmintime = curr_time + vsynctime;
-           rpt_did_reset = 0;
-       }
-       /* Allow this to be one frame's worth of cycles out */
-       while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) {
-           vsyncmintime += vsynctime * N_LINES / maxvpos;
-           gonebad++;
-           if (turbo_emulation)
-               break;
-       }
-    }
-}
-#endif
-
-static void copper_check (int n)
-{
-    if (cop_state.state == COP_wait) {
-       int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80);
-       if (vp < cop_state.vcmp) {
-           if (eventtab[ev_copper].active || copper_enabled_thisline)
-               write_log ("COPPER BUG %d: vp=%d vpos=%d vcmp=%d act=%d thisline=%d\n", n, vp, vpos, cop_state.vcmp, eventtab[ev_copper].active, copper_enabled_thisline);
-       }
-    }
-}
-
-static void hsync_handler (void)
-{
-    static int ciahsync;
-    int hpos = current_hpos ();
-
-    /* Using 0x8A makes sure that we don't accidentally trip over the
-       modified_regtypes check.  */
-    sync_copper_with_cpu (maxhpos, 0, 0x8A);
-
-    //copper_check (1);
-
-    finish_decisions ();
-    if (thisline_decision.plfleft != -1) {
-       if (currprefs.collision_level > 1)
-           do_sprite_collisions ();
-       if (currprefs.collision_level > 2)
-           do_playfield_collisions ();
-    }
-    hsync_record_line_state (next_lineno, nextline_how, thisline_changed);
-
-    eventtab[ev_hsync].evtime += get_cycles () - eventtab[ev_hsync].oldcycles;
-    eventtab[ev_hsync].oldcycles = get_cycles ();
-    CIA_hsync_handler ();
-#ifdef CD32
-    AKIKO_hsync_handler ();
-#endif
-
-#ifdef PICASSO96
-    picasso_handle_hsync ();
-#endif
-    ciahsync++;
-    if (ciahsync >= (currprefs.ntscmode ? MAXVPOS_NTSC : MAXVPOS_PAL) * MAXHPOS_PAL / maxhpos) { /* not so perfect.. */
-        CIA_vsync_handler ();
-       ciahsync = 0;
-    }
-
-#ifdef CPUEMU_6
-    if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
-        decide_blitter (hpos);
-       memset (cycle_line, 0, MAXHPOS);
-       cycle_line[maxhpos - 1] = CYCLE_REFRESH;
-       cycle_line[0] = CYCLE_REFRESH;
-       cycle_line[2] = CYCLE_REFRESH;
-       cycle_line[4] = CYCLE_REFRESH;
-    }
-#endif
-    if ((currprefs.chipset_mask & CSMASK_AGA) || (!currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       last_custom_value = rand ();
-    else
-       last_custom_value = 0xffff;
-
-    if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop)
-       blitter_slowdown (ddfstrt, ddfstop, cycle_diagram_total_cycles[fmode][GET_RES (bplcon0)][GET_PLANES (bplcon0)],
-           cycle_diagram_free_cycles[fmode][GET_RES (bplcon0)][GET_PLANES (bplcon0)]);
-
-    if (currprefs.produce_sound)
-       audio_hsync (1);
-
-    hardware_line_completed (next_lineno);
-
-    /* In theory only an equality test is needed here - but if a program
-       goes haywire with the VPOSW register, it can cause us to miss this,
-       with vpos going into the thousands (and all the nasty consequences
-       this has).  */
-
-    if (++vpos >= (maxvpos + (lof == 0 ? 0 : 1))) {
-       vpos = 0;
-       vsync_handler ();
-    }
-
-    DISK_update (maxhpos);
-
-#ifdef JIT
-    if (compiled_code) {
-       if (currprefs.m68k_speed == -1) {
-           static int count=0;
-
-           count++;
-           if (trigger_frh(count)) {
-               frh_handler();
-           }
-           is_lastline = trigger_frh(count+1) && ! rpt_did_reset;
-       }
-       else
-           is_lastline=0;
-    } else {
-#endif
-       is_lastline = vpos + 1 == maxvpos + (lof == 0 ? 0 : 1) && currprefs.m68k_speed == -1 && ! rpt_did_reset;
-#ifdef JIT
-    }
-#endif
-
-    if ((bplcon0 & 4) && currprefs.gfx_linedbl)
-       notice_interlace_seen ();
-
-    if (framecnt == 0) {
-       int lineno = vpos;
-       nextline_how = nln_normal;
-       if (currprefs.gfx_linedbl) {
-           lineno *= 2;
-           nextline_how = currprefs.gfx_linedbl == 1 ? nln_doubled : nln_nblack;
-           if (bplcon0 & 4) {
-               if (!lof) {
-                   lineno++;
-                   nextline_how = nln_lower;
-               } else {
-                   nextline_how = nln_upper;
-               }
-           }
-       }
-       next_lineno = lineno;
-       reset_decisions ();
-    }
-#ifdef FILESYS    
-    if (uae_int_requested) {
-       set_uae_int_flag ();
-       INTREQ (0x8000 | 0x0008);
-    }
-#endif
-    /* See if there's a chance of a copper wait ending this line.  */
-    cop_state.hpos = 0;
-    compute_spcflag_copper ();
-    inputdevice_hsync ();
-    serial_hsynchandler ();
-#ifdef CUSTOM_SIMPLE
-    do_sprites (0);
-#endif
-    //copper_check (2);
-}
-
-static void init_regtypes (void)
-{
-    int i;
-    for (i = 0; i < 512; i += 2) {
-       regtypes[i] = REGTYPE_ALL;
-       if ((i >= 0x20 && i < 0x28) || i == 0x08 || i == 0x7E)
-           regtypes[i] = REGTYPE_DISK;
-       else if (i >= 0x68 && i < 0x70)
-           regtypes[i] = REGTYPE_NONE;
-       else if (i >= 0x40 && i < 0x78)
-           regtypes[i] = REGTYPE_BLITTER;
-       else if (i >= 0xA0 && i < 0xE0 && (i & 0xF) < 0xE)
-           regtypes[i] = REGTYPE_AUDIO;
-       else if (i >= 0xA0 && i < 0xE0)
-           regtypes[i] = REGTYPE_NONE;
-       else if (i >= 0xE0 && i < 0x100)
-           regtypes[i] = REGTYPE_PLANE;
-       else if (i >= 0x120 && i < 0x180)
-           regtypes[i] = REGTYPE_SPRITE;
-       else if (i >= 0x180 && i < 0x1C0)
-           regtypes[i] = REGTYPE_COLOR;
-       else switch (i) {
-       case 0x02:
-           /* DMACONR - setting this to REGTYPE_BLITTER will cause it to
-              conflict with DMACON (since that is REGTYPE_ALL), and the
-              blitter registers (for the BBUSY bit), but nothing else,
-              which is (I think) what we want.  */
-           regtypes[i] = REGTYPE_BLITTER;
-           break;
-       case 0x04: case 0x06: case 0x2A: case 0x2C:
-           regtypes[i] = REGTYPE_POS;
-           break;
-       case 0x0A: case 0x0C:
-       case 0x12: case 0x14: case 0x16:
-       case 0x36:
-           regtypes[i] = REGTYPE_JOYPORT;
-           break;
-       case 0x104:
-       case 0x102:
-           regtypes[i] = REGTYPE_PLANE;
-           break;
-       case 0x88: case 0x8A:
-       case 0x8E: case 0x90: case 0x92: case 0x94:
-       case 0x96:
-       case 0x100:
-           regtypes[i] |= REGTYPE_FORCE;
-           break;
-       }
-    }
-}
-
-void init_eventtab (void)
-{
-    int i;
-
-    nextevent = 0;
-    set_cycles (0);
-    for (i = 0; i < ev_max; i++) {
-       eventtab[i].active = 0;
-       eventtab[i].oldcycles = 0;
-    }
-
-    eventtab[ev_cia].handler = CIA_handler;
-    eventtab[ev_hsync].handler = hsync_handler;
-    eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME;
-    eventtab[ev_hsync].active = 1;
-
-    eventtab[ev_copper].handler = copper_handler;
-    eventtab[ev_copper].active = 0;
-    eventtab[ev_blitter].handler = blitter_handler;
-    eventtab[ev_blitter].active = 0;
-    eventtab[ev_disk].handler = DISK_handler;
-    eventtab[ev_disk].active = 0;
-    eventtab[ev_audio].handler = audio_evhandler;
-    eventtab[ev_audio].active = 0;
-    events_schedule ();
-}
-
-void customreset (void)
-{
-    int i;
-    int zero = 0;
-
-    write_log ("reset at %x\n", m68k_getpc());
-    if (! savestate_state) {
-       currprefs.chipset_mask = changed_prefs.chipset_mask;
-       if ((currprefs.chipset_mask & CSMASK_AGA) == 0) {
-           for (i = 0; i < 32; i++) {
-               current_colors.color_regs_ecs[i] = 0;
-               current_colors.acolors[i] = xcolors[0];
-           }
-#ifdef AGA
-       } else {
-            for (i = 0; i < 256; i++) {
-               current_colors.color_regs_aga[i] = 0;
-               current_colors.acolors[i] = CONVERT_RGB (zero);
-           }
-#endif
-       }
-
-       clxdat = 0;
-
-       /* Clear the armed flags of all sprites.  */
-       memset (spr, 0, sizeof spr);
-       nr_armed = 0;
-
-       dmacon = intena = 0;
-
-       copcon = 0;
-       DSKLEN (0, 0);
-
-       bplcon0 = 0;
-       bplcon4 = 0x11; /* Get AGA chipset into ECS compatibility mode */
-       bplcon3 = 0xC00;
-
-       FMODE (0);
-       CLXCON (0);
-    }
-
-#ifdef AUTOCONFIG
-    expamem_reset ();
-#endif
-    a1000_reset ();
-    DISK_reset ();
-    CIA_reset ();
-#ifdef JIT
-    compemu_reset ();
-#endif
-    unset_special (~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE));
-
-    vpos = 0;
-
-    if (needmousehack ()) {
-#if 0
-       mousehack_set (mousehack_follow);
-#else
-       mousehack_set (mousehack_dontcare);
-#endif
-    } else {
-       mousehack_set (mousehack_normal);
-    }
-    ievent_alive = 0;
-    timehack_alive = 0;
-
-    curr_sprite_entries = 0;
-    prev_sprite_entries = 0;
-    sprite_entries[0][0].first_pixel = 0;
-    sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS;
-    sprite_entries[0][1].first_pixel = 0;
-    sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS;
-    memset (spixels, 0, sizeof spixels);
-    memset (&spixstate, 0, sizeof spixstate);
-
-    bltstate = BLT_done;
-    cop_state.state = COP_stop;
-    diwstate = DIW_waiting_start;
-    hdiwstate = DIW_waiting_start;
-    set_cycles (0);
-
-    new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
-    hack_vpos = 0;
-    init_hz ();
-
-    audio_reset ();
-    if (savestate_state != STATE_RESTORE) {
-       /* must be called after audio_reset */
-       adkcon = 0;
-       serial_uartbreak (0);
-       update_adkmasks ();
-    }
-
-    init_sprites ();
-
-    init_hardware_frame ();
-    drawing_init ();
-
-    reset_decisions ();
-
-    bogusframe = 1;
-
-    init_regtypes ();
-
-    sprite_buffer_res = currprefs.chipset_mask & CSMASK_AGA ? RES_HIRES : RES_LORES;
-    if (savestate_state == STATE_RESTORE) {
-       uae_u16 v;
-       uae_u32 vv;
-
-       update_adkmasks ();
-       INTENA (0);
-       INTREQ (0);
-#if 0
-       DMACON (0, 0);
-#endif
-       COPJMP (1);
-       v = bplcon0;
-       BPLCON0 (0, 0);
-       BPLCON0 (0, v);
-       FMODE (fmode);
-       if (!(currprefs.chipset_mask & CSMASK_AGA)) {
-           for(i = 0 ; i < 32 ; i++)  {
-               vv = current_colors.color_regs_ecs[i];
-               current_colors.color_regs_ecs[i] = -1;
-               record_color_change (0, i, vv);
-               remembered_color_entry = -1;
-               current_colors.color_regs_ecs[i] = vv;
-               current_colors.acolors[i] = xcolors[vv];
-           }
-#ifdef AGA
-       } else {
-           for(i = 0 ; i < 256 ; i++)  {
-               vv = current_colors.color_regs_aga[i];
-               current_colors.color_regs_aga[i] = -1;
-               record_color_change (0, i, vv);
-               remembered_color_entry = -1;
-               current_colors.color_regs_aga[i] = vv;
-               current_colors.acolors[i] = CONVERT_RGB(vv);
-           }
-#endif
-       }
-       CLXCON (clxcon);
-       CLXCON2 (clxcon2);
-       calcdiw ();
-       write_log ("State restored\n");
-       dumpcustom ();
-       for (i = 0; i < 8; i++)
-           nr_armed += spr[i].armed != 0;
-    }
-    expand_sprres ();
-
-    #ifdef ACTION_REPLAY
-    /* Doing this here ensures we can use the 'reset' command from within AR */
-    action_replay_reset ();
-    #endif
-    #ifdef WIN32
-    #ifndef UAE_MINI
-    enforcer_disable();
-    #endif
-    #endif
-}
-
-void dumpcustom (void)
-{
-    write_log ("DMACON: %x INTENA: %x INTREQ: %x VPOS: %x HPOS: %x\n", DMACONR(),
-              (unsigned int)intena, (unsigned int)intreq, (unsigned int)vpos, (unsigned int)current_hpos());
-    write_log ("COP1LC: %08lx, COP2LC: %08lx COPPTR: %08lx\n", (unsigned long)cop1lc, (unsigned long)cop2lc, cop_state.ip);
-    write_log ("DIWSTRT: %04x DIWSTOP: %04x DDFSTRT: %04x DDFSTOP: %04x\n",
-              (unsigned int)diwstrt, (unsigned int)diwstop, (unsigned int)ddfstrt, (unsigned int)ddfstop);
-    write_log ("BPLCON 0: %04x 1: %04x 2: %04x 3: %04x 4: %04x\n", bplcon0, bplcon1, bplcon2, bplcon3, bplcon4);
-    if (timeframes) {
-       write_log ("Average frame time: %f ms [frames: %d time: %d]\n",
-                  (double)frametime / timeframes, timeframes, frametime);
-       if (total_skipped)
-           write_log ("Skipped frames: %d\n", total_skipped);
-    }
-    /*for (i=0; i<256; i++) if (blitcount[i]) write_log ("minterm %x = %d\n",i,blitcount[i]);  blitter debug */
-}
-
-static void gen_custom_tables (void)
-{
-    int i;
-    for (i = 0; i < 256; i++) {
-       sprtaba[i] = ((((i >> 7) & 1) << 0)
-                     | (((i >> 6) & 1) << 2)
-                     | (((i >> 5) & 1) << 4)
-                     | (((i >> 4) & 1) << 6)
-                     | (((i >> 3) & 1) << 8)
-                     | (((i >> 2) & 1) << 10)
-                     | (((i >> 1) & 1) << 12)
-                     | (((i >> 0) & 1) << 14));
-       sprtabb[i] = sprtaba[i] * 2;
-       sprite_ab_merge[i] = (((i & 15) ? 1 : 0)
-                             | ((i & 240) ? 2 : 0));
-    }
-    for (i = 0; i < 16; i++) {
-       clxmask[i] = (((i & 1) ? 0xF : 0x3)
-                     | ((i & 2) ? 0xF0 : 0x30)
-                     | ((i & 4) ? 0xF00 : 0x300)
-                     | ((i & 8) ? 0xF000 : 0x3000));
-       sprclx[i] = (((i & 0x3) == 0x3 ? 1 : 0)
-                    | ((i & 0x5) == 0x5 ? 2 : 0)
-                    | ((i & 0x9) == 0x9 ? 4 : 0)
-                    | ((i & 0x6) == 0x6 ? 8 : 0)
-                    | ((i & 0xA) == 0xA ? 16 : 0)
-                    | ((i & 0xC) == 0xC ? 32 : 0)) << 9;
-    }
-}
-
-void custom_init (void)
-{
-
-#ifdef OS_WITHOUT_MEMORY_MANAGEMENT
-    int num;
-
-    for (num = 0; num < 2; num++) {
-       sprite_entries[num] = xmalloc (max_sprite_entry * sizeof (struct sprite_entry));
-       color_changes[num] = xmalloc (max_color_change * sizeof (struct color_change));
-    }
-#endif
-
-#ifdef AUTOCONFIG
-    {
-       uaecptr pos;
-       pos = here ();
-
-       org (RTAREA_BASE+0xFF70);
-       calltrap (deftrap (mousehack_helper));
-       dw (RTS);
-
-       org (RTAREA_BASE+0xFFA0);
-       calltrap (deftrap (timehack_helper));
-       dw (RTS);
-
-       org (pos);
-    }
-#endif
-
-    gen_custom_tables ();
-    build_blitfilltable ();
-
-    drawing_init ();
-
-    mousehack_set (mousehack_unknown);
-    if (needmousehack ())
-       mousehack_set (mousehack_follow);
-
-    create_cycle_diagram_table ();
-}
-
-/* Custom chip memory bank */
-
-static uae_u32 custom_lget (uaecptr) REGPARAM;
-static uae_u32 custom_wget (uaecptr) REGPARAM;
-static uae_u32 custom_bget (uaecptr) REGPARAM;
-static void custom_lput (uaecptr, uae_u32) REGPARAM;
-static void custom_wput (uaecptr, uae_u32) REGPARAM;
-static void custom_bput (uaecptr, uae_u32) REGPARAM;
-
-addrbank custom_bank = {
-    custom_lget, custom_wget, custom_bget,
-    custom_lput, custom_wput, custom_bput,
-    default_xlate, default_check, NULL
-};
-
-STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (uaecptr addr, int noput)
-{
-    uae_u16 v;
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    addr &= 0xfff;
-#ifdef CUSTOM_DEBUG
-    write_log ("%d:%d:wget: %04.4X=%04.4X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc());
-#endif
-    switch (addr & 0x1fe) {
-     case 0x002: v = DMACONR (); break;
-     case 0x004: v = VPOSR (); break;
-     case 0x006: v = VHPOSR (); break;
-
-     case 0x00A: v = JOY0DAT (); break;
-     case 0x00C: v = JOY1DAT (); break;
-     case 0x00E: v = CLXDAT (); break;
-     case 0x010: v = ADKCONR (); break;
-
-     case 0x012: v = POT0DAT (); break;
-     case 0x014: v = POT1DAT (); break;
-     case 0x016: v = POTGOR (); break;
-     case 0x018: v = SERDATR (); break;
-     case 0x01A: v = DSKBYTR (current_hpos ()); break;
-     case 0x01C: v = INTENAR (); break;
-     case 0x01E: v = INTREQR (); break;
-     case 0x07C: v = DENISEID (); break;
-
-     case 0x02E: v = 0xffff; break; /* temporary hack */
-
-#ifdef AGA
-     case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
-     case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
-     case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2:
-     case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
-     case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
-     case 0x1BC: case 0x1BE:
-       v = COLOR_READ ((addr & 0x3E) / 2);
-       break;
-#endif
-
-     default:
-       /* reading write-only register causes write with last value in bus */
-        v = last_custom_value;
-       if (!noput) {
-           int r;
-           int hpos = current_hpos ();
-            decide_line (hpos);
-           decide_fetch (hpos);
-           decide_blitter (hpos);
-            v = last_custom_value;
-           r = custom_wput_1 (hpos, addr, v, 1);
-       }
-       return v;
-    }
-    return v;
-}
-
- STATIC_INLINE custom_wget2 (uaecptr addr)
- {
-    uae_u32 v;
-    sync_copper_with_cpu (current_hpos (), 1, addr);
-    if (currprefs.cpu_level >= 2) {
-       if(addr > 0xde0000 && addr <= 0xdeffff)
-           return 0x7f7f;
-       if(addr > 0xdd0000 && addr <= 0xddffff)
-            return 0xffff;
-    }
-    v = custom_wget_1 (addr, 0);
-#ifdef ACTION_REPLAY
-#ifdef ACTION_REPLAY_COMMON
-    addr &= 0x1ff;
-    ar_custom[addr + 0] = (uae_u8)(v >> 8);
-    ar_custom[addr + 1] = (uae_u8)(v);
-#endif
-#endif
-    return v;
-}
-
-uae_u32 REGPARAM2 custom_wget (uaecptr addr)
-{
-    uae_u32 v;
-
-    if (addr & 1) {
-       /* think about move.w $dff005,d0.. (68020+ only) */
-       addr &= ~1;
-       v = custom_wget2 (addr) << 8;
-       v |= custom_wget2 (addr + 2) >> 8;
-       return v;
-    }
-    return custom_wget2 (addr);
- }
-uae_u32 REGPARAM2 custom_bget (uaecptr addr)
-{
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    return custom_wget2 (addr & ~1) >> (addr & 1 ? 0 : 8);
-}
-
-uae_u32 REGPARAM2 custom_lget (uaecptr addr)
-{
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    return ((uae_u32)custom_wget (addr) << 16) | custom_wget (addr + 2);
-}
-
-int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int noget)
-{
-    addr &= 0x1FE;
-    value &= 0xffff;
-#ifdef ACTION_REPLAY
-#ifdef ACTION_REPLAY_COMMON
-    ar_custom[addr+0]=(uae_u8)(value>>8);
-    ar_custom[addr+1]=(uae_u8)(value);
-#endif
-#endif
-    last_custom_value = value;
-    switch (addr) {
-     case 0x00E: CLXDAT (); break;
-
-     case 0x020: DSKPTH (value); break;
-     case 0x022: DSKPTL (value); break;
-     case 0x024: DSKLEN (value, hpos); break;
-     case 0x026: DSKDAT (value); break;
-
-     case 0x02A: VPOSW (value); break;
-     case 0x02E: COPCON (value); break;
-     case 0x030: SERDAT (value); break;
-     case 0x032: SERPER (value); break;
-     case 0x034: POTGO (value); break;
-     case 0x040: BLTCON0 (value); break;
-     case 0x042: BLTCON1 (value); break;
-
-     case 0x044: BLTAFWM (value); break;
-     case 0x046: BLTALWM (value); break;
-
-     case 0x050: BLTAPTH (value); break;
-     case 0x052: BLTAPTL (value); break;
-     case 0x04C: BLTBPTH (value); break;
-     case 0x04E: BLTBPTL (value); break;
-     case 0x048: BLTCPTH (value); break;
-     case 0x04A: BLTCPTL (value); break;
-     case 0x054: BLTDPTH (value); break;
-     case 0x056: BLTDPTL (value); break;
-
-     case 0x058: BLTSIZE (value); break;
-
-     case 0x064: BLTAMOD (value); break;
-     case 0x062: BLTBMOD (value); break;
-     case 0x060: BLTCMOD (value); break;
-     case 0x066: BLTDMOD (value); break;
-
-     case 0x070: BLTCDAT (value); break;
-     case 0x072: BLTBDAT (value); break;
-     case 0x074: BLTADAT (value); break;
-
-     case 0x07E: DSKSYNC (hpos, value); break;
-
-     case 0x080: COP1LCH (value); break;
-     case 0x082: COP1LCL (value); break;
-     case 0x084: COP2LCH (value); break;
-     case 0x086: COP2LCL (value); break;
-
-     case 0x088: COPJMP (1); break;
-     case 0x08A: COPJMP (2); break;
-
-     case 0x08E: DIWSTRT (hpos, value); break;
-     case 0x090: DIWSTOP (hpos, value); break;
-     case 0x092: DDFSTRT (hpos, value); break;
-     case 0x094: DDFSTOP (hpos, value); break;
-
-     case 0x096: DMACON (hpos, value); break;
-     case 0x098: CLXCON (value); break;
-     case 0x09A: INTENA (value); break;
-     case 0x09C: INTREQ (value); break;
-     case 0x09E: ADKCON (hpos, value); break;
-
-     case 0x0A0: AUDxLCH (0, value); break;
-     case 0x0A2: AUDxLCL (0, value); break;
-     case 0x0A4: AUDxLEN (0, value); break;
-     case 0x0A6: AUDxPER (0, value); break;
-     case 0x0A8: AUDxVOL (0, value); break;
-     case 0x0AA: AUDxDAT (0, value); break;
-
-     case 0x0B0: AUDxLCH (1, value); break;
-     case 0x0B2: AUDxLCL (1, value); break;
-     case 0x0B4: AUDxLEN (1, value); break;
-     case 0x0B6: AUDxPER (1, value); break;
-     case 0x0B8: AUDxVOL (1, value); break;
-     case 0x0BA: AUDxDAT (1, value); break;
-
-     case 0x0C0: AUDxLCH (2, value); break;
-     case 0x0C2: AUDxLCL (2, value); break;
-     case 0x0C4: AUDxLEN (2, value); break;
-     case 0x0C6: AUDxPER (2, value); break;
-     case 0x0C8: AUDxVOL (2, value); break;
-     case 0x0CA: AUDxDAT (2, value); break;
-
-     case 0x0D0: AUDxLCH (3, value); break;
-     case 0x0D2: AUDxLCL (3, value); break;
-     case 0x0D4: AUDxLEN (3, value); break;
-     case 0x0D6: AUDxPER (3, value); break;
-     case 0x0D8: AUDxVOL (3, value); break;
-     case 0x0DA: AUDxDAT (3, value); break;
-
-     case 0x0E0: BPLxPTH (hpos, value, 0); break;
-     case 0x0E2: BPLxPTL (hpos, value, 0); break;
-     case 0x0E4: BPLxPTH (hpos, value, 1); break;
-     case 0x0E6: BPLxPTL (hpos, value, 1); break;
-     case 0x0E8: BPLxPTH (hpos, value, 2); break;
-     case 0x0EA: BPLxPTL (hpos, value, 2); break;
-     case 0x0EC: BPLxPTH (hpos, value, 3); break;
-     case 0x0EE: BPLxPTL (hpos, value, 3); break;
-     case 0x0F0: BPLxPTH (hpos, value, 4); break;
-     case 0x0F2: BPLxPTL (hpos, value, 4); break;
-     case 0x0F4: BPLxPTH (hpos, value, 5); break;
-     case 0x0F6: BPLxPTL (hpos, value, 5); break;
-     case 0x0F8: BPLxPTH (hpos, value, 6); break;
-     case 0x0FA: BPLxPTL (hpos, value, 6); break;
-     case 0x0FC: BPLxPTH (hpos, value, 7); break;
-     case 0x0FE: BPLxPTL (hpos, value, 7); break;
-
-     case 0x100: BPLCON0 (hpos, value); break;
-     case 0x102: BPLCON1 (hpos, value); break;
-     case 0x104: BPLCON2 (hpos, value); break;
-#ifdef AGA
-     case 0x106: BPLCON3 (hpos, value); break;
-#endif
-
-     case 0x108: BPL1MOD (hpos, value); break;
-     case 0x10A: BPL2MOD (hpos, value); break;
-#ifdef AGA
-     case 0x10E: CLXCON2 (value); break;
-#endif
-
-     case 0x110: BPL1DAT (hpos, value); break;
-     case 0x112: BPL2DAT (value); break;
-     case 0x114: BPL3DAT (value); break;
-     case 0x116: BPL4DAT (value); break;
-     case 0x118: BPL5DAT (value); break;
-     case 0x11A: BPL6DAT (value); break;
-     case 0x11C: BPL7DAT (value); break;
-     case 0x11E: BPL8DAT (value); break;
-
-     case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
-     case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
-     case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2:
-     case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
-     case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
-     case 0x1BC: case 0x1BE:
-       COLOR_WRITE (hpos, value & 0xFFF, (addr & 0x3E) / 2);
-       break;
-     case 0x120: case 0x124: case 0x128: case 0x12C:
-     case 0x130: case 0x134: case 0x138: case 0x13C:
-       SPRxPTH (hpos, value, (addr - 0x120) / 4);
-       break;
-     case 0x122: case 0x126: case 0x12A: case 0x12E:
-     case 0x132: case 0x136: case 0x13A: case 0x13E:
-       SPRxPTL (hpos, value, (addr - 0x122) / 4);
-       break;
-     case 0x140: case 0x148: case 0x150: case 0x158:
-     case 0x160: case 0x168: case 0x170: case 0x178:
-       SPRxPOS (hpos, value, (addr - 0x140) / 8);
-       break;
-     case 0x142: case 0x14A: case 0x152: case 0x15A:
-     case 0x162: case 0x16A: case 0x172: case 0x17A:
-       SPRxCTL (hpos, value, (addr - 0x142) / 8);
-       break;
-     case 0x144: case 0x14C: case 0x154: case 0x15C:
-     case 0x164: case 0x16C: case 0x174: case 0x17C:
-       SPRxDATA (hpos, value, (addr - 0x144) / 8);
-       break;
-     case 0x146: case 0x14E: case 0x156: case 0x15E:
-     case 0x166: case 0x16E: case 0x176: case 0x17E:
-       SPRxDATB (hpos, value, (addr - 0x146) / 8);
-       break;
-
-     case 0x36: JOYTEST (value); break;
-     case 0x5A: BLTCON0L (value); break;
-     case 0x5C: BLTSIZV (value); break;
-     case 0x5E: BLTSIZH (value); break;
-     case 0x1E4: DIWHIGH (hpos, value); break;
-#ifdef AGA
-     case 0x10C: BPLCON4 (hpos, value); break;
-#endif
-
-     case 0x1DC: BEAMCON0 (value); break;
-     case 0x1C0: if (htotal != value) { htotal = value; varsync (); } break;
-     case 0x1C2: if (hsstop != value) { hsstop = value; varsync (); } break;
-     case 0x1C4: if (hbstrt != value) { hbstrt = value; varsync (); } break;
-     case 0x1C6: if (hbstop != value) { hbstop = value; varsync (); } break;
-     case 0x1C8: if (vtotal != value) { vtotal = value; varsync (); } break;
-     case 0x1CA: if (vsstop != value) { vsstop = value; varsync (); } break;
-     case 0x1CC: if (vbstrt != value) { vbstrt = value; varsync (); } break;
-     case 0x1CE: if (vbstop != value) { vbstop = value; varsync (); } break;
-     case 0x1DE: if (hsstrt != value) { hsstrt = value; varsync (); } break;
-     case 0x1E0: if (vsstrt != value) { vsstrt = value; varsync (); } break;
-     case 0x1E2: if (hcenter != value) { hcenter = value; varsync (); } break;
-
-#ifdef AGA
-     case 0x1FC: FMODE (value); break;
-#endif
-
-     /* writing to read-only register causes read access */
-     default:
-       if (!noget)
-           custom_wget_1 (addr, 1);
-        if (!(currprefs.chipset_mask & CSMASK_AGA) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-           last_custom_value = 0xffff;
-       return 1;
-    }
-    return 0;
-}
-
-void REGPARAM2 custom_wput (uaecptr addr, uae_u32 value)
-{
-    int hpos = current_hpos ();
-#ifdef JIT
-    special_mem |= S_WRITE;
-#endif
-#ifdef CUSTOM_DEBUG
-    write_log ("%d:%d:wput: %04.4X %04.4X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc());
-#endif
-    sync_copper_with_cpu (hpos, 1, addr);
-    custom_wput_1 (hpos, addr, value, 0);
-}
-
-void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value)
-{
-    static int warned;
-    /* Is this correct now? (There are people who bput things to the upper byte of AUDxVOL). */
-    uae_u16 rval = (value << 8) | (value & 0xFF);
-#ifdef JIT
-    special_mem |= S_WRITE;
-#endif
-    custom_wput (addr & ~1, rval);
-    if (warned < 10) {
-       write_log ("Byte put to custom register %04.4X PC=%08.8X\n", addr, m68k_getpc());
-       warned++;
-    }
-}
-
-void REGPARAM2 custom_lput(uaecptr addr, uae_u32 value)
-{
-#ifdef JIT
-    special_mem |= S_WRITE;
-#endif
-    custom_wput (addr & 0xfffe, value >> 16);
-    custom_wput ((addr + 2) & 0xfffe, (uae_u16)value);
-}
-
-void custom_prepare_savestate (void)
-{
-}
-
-#define RB restore_u8 ()
-#define RW restore_u16 ()
-#define RL restore_u32 ()
-
-uae_u8 *restore_custom (uae_u8 *src)
-{
-    uae_u16 dsklen, dskbytr;
-    int dskpt;
-    int i;
-
-    audio_reset ();
-
-    changed_prefs.chipset_mask = currprefs.chipset_mask = RL;
-    RW;                                /* 000 ? */
-    RW;                                /* 002 DMACONR */
-    RW;                                /* 004 VPOSR */
-    RW;                                /* 006 VHPOSR */
-    RW;                                /* 008 DSKDATR (dummy register) */
-    RW;                                /* 00A JOY0DAT */
-    RW;                                /* 00C JOY1DAT */
-    clxdat = RW;               /* 00E CLXDAT */
-    RW;                                /* 010 ADKCONR */
-    RW;                                /* 012 POT0DAT* */
-    RW;                                /* 014 POT1DAT* */
-    RW;                                /* 016 POTINP* */
-    RW;                                /* 018 SERDATR* */
-    dskbytr = RW;              /* 01A DSKBYTR */
-    RW;                                /* 01C INTENAR */
-    RW;                                /* 01E INTREQR */
-    dskpt = RL;                        /* 020-022 DSKPT */
-    dsklen = RW;               /* 024 DSKLEN */
-    RW;                                /* 026 DSKDAT */
-    RW;                                /* 028 REFPTR */
-    lof = RW;                  /* 02A VPOSW */
-    RW;                                /* 02C VHPOSW */
-    COPCON(RW);                        /* 02E COPCON */
-    RW;                                /* 030 SERDAT* */
-    RW;                                /* 032 SERPER* */
-    POTGO(RW);                 /* 034 POTGO */
-    RW;                                /* 036 JOYTEST* */
-    RW;                                /* 038 STREQU */
-    RW;                                /* 03A STRVHBL */
-    RW;                                /* 03C STRHOR */
-    RW;                                /* 03E STRLONG */
-    BLTCON0(RW);               /* 040 BLTCON0 */
-    BLTCON1(RW);               /* 042 BLTCON1 */
-    BLTAFWM(RW);               /* 044 BLTAFWM */
-    BLTALWM(RW);               /* 046 BLTALWM */
-    BLTCPTH(RL);               /* 048-04B BLTCPT */
-    BLTBPTH(RL);               /* 04C-04F BLTBPT */
-    BLTAPTH(RL);               /* 050-053 BLTAPT */
-    BLTDPTH(RL);               /* 054-057 BLTDPT */
-    RW;                                /* 058 BLTSIZE */
-    RW;                                /* 05A BLTCON0L */
-    blt_info.vblitsize = RW;   /* 05C BLTSIZV */
-    blt_info.hblitsize = RW;   /* 05E BLTSIZH */
-    BLTCMOD(RW);               /* 060 BLTCMOD */
-    BLTBMOD(RW);               /* 062 BLTBMOD */
-    BLTAMOD(RW);               /* 064 BLTAMOD */
-    BLTDMOD(RW);               /* 066 BLTDMOD */
-    RW;                                /* 068 ? */
-    RW;                                /* 06A ? */
-    RW;                                /* 06C ? */
-    RW;                                /* 06E ? */
-    BLTCDAT(RW);               /* 070 BLTCDAT */
-    BLTBDAT(RW);               /* 072 BLTBDAT */
-    BLTADAT(RW);               /* 074 BLTADAT */
-    RW;                                /* 076 ? */
-    RW;                                /* 078 ? */
-    RW;                                /* 07A ? */
-    RW;                                /* 07C LISAID */
-    DSKSYNC(-1, RW);           /* 07E DSKSYNC */
-    cop1lc = RL;               /* 080/082 COP1LC */
-    cop2lc = RL;               /* 084/086 COP2LC */
-    RW;                                /* 088 ? */
-    RW;                                /* 08A ? */
-    RW;                                /* 08C ? */
-    diwstrt = RW;              /* 08E DIWSTRT */
-    diwstop = RW;              /* 090 DIWSTOP */
-    ddfstrt = RW;              /* 092 DDFSTRT */
-    ddfstop = RW;              /* 094 DDFSTOP */
-    dmacon = RW & ~(0x2000|0x4000); /* 096 DMACON */
-    CLXCON(RW);                        /* 098 CLXCON */
-    intena = RW;               /* 09A INTENA */
-    intreq = RW;               /* 09C INTREQ */
-    adkcon = RW;               /* 09E ADKCON */
-    for (i = 0; i < 8; i++)
-       bplpt[i] = RL;
-    bplcon0 = RW;              /* 100 BPLCON0 */
-    bplcon1 = RW;              /* 102 BPLCON1 */
-    bplcon2 = RW;              /* 104 BPLCON2 */
-    bplcon3 = RW;              /* 106 BPLCON3 */
-    bpl1mod = RW;              /* 108 BPL1MOD */
-    bpl2mod = RW;              /* 10A BPL2MOD */
-    bplcon4 = RW;              /* 10C BPLCON4 */
-    clxcon2 = RW;              /* 10E CLXCON2* */
-    for(i = 0; i < 8; i++)
-       RW;                     /*     BPLXDAT */
-    for(i = 0; i < 32; i++)
-       current_colors.color_regs_ecs[i] = RW; /* 180 COLORxx */
-    htotal = RW;               /* 1C0 HTOTAL */
-    RW;                                /* 1C2 ? */
-    RW;                                /* 1C4 ? */
-    RW;                                /* 1C6 ? */
-    vtotal = RW;               /* 1C8 VTOTAL */
-    RW;                                /* 1CA ? */
-    RW;                                /* 1CC ? */
-    RW;                                /* 1CE ? */
-    RW;                                /* 1D0 ? */
-    RW;                                /* 1D2 ? */
-    RW;                                /* 1D4 ? */
-    RW;                                /* 1D6 ? */
-    RW;                                /* 1D8 ? */
-    RW;                                /* 1DA ? */
-    new_beamcon0 = RW;         /* 1DC BEAMCON0 */
-    RW;                                /* 1DE ? */
-    RW;                                /* 1E0 ? */
-    RW;                                /* 1E2 ? */
-    diwhigh = RW;              /* 1E4 ? */
-    if (diwhigh & 0x8000)
-       diwhigh_written = 1;
-    diwhigh &= 0x7fff;
-    RW;                                /* 1E6 ? */
-    RW;                                /* 1E8 ? */
-    RW;                                /* 1EA ? */
-    RW;                                /* 1EC ? */
-    RW;                                /* 1EE ? */
-    RW;                                /* 1F0 ? */
-    RW;                                /* 1F2 ? */
-    RW;                                /* 1F4 ? */
-    RW;                                /* 1F6 ? */
-    RW;                                /* 1F8 ? */
-    RW;                                /* 1FA ? */
-    fmode = RW;                        /* 1FC FMODE */
-    last_custom_value = RW;    /* 1FE ? */
-
-    DISK_restore_custom (dskpt, dsklen, dskbytr);
-
-    return src;
-}
-
-
-#define SB save_u8
-#define SW save_u16
-#define SL save_u32
-
-extern uae_u16 serper;
-
-uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full)
-{
-    uae_u8 *dstbak, *dst;
-    int i;
-    uae_u32 dskpt;
-    uae_u16 dsklen, dsksync, dskbytr;
-
-    DISK_save_custom (&dskpt, &dsklen, &dsksync, &dskbytr);
-
-    if (dstptr)
-       dstbak = dst = dstptr;
-    else
-        dstbak = dst = malloc (8+256*2);
-
-    SL (currprefs.chipset_mask);
-    SW (0);                    /* 000 ? */
-    SW (dmacon);               /* 002 DMACONR */
-    SW (VPOSR());              /* 004 VPOSR */
-    SW (VHPOSR());             /* 006 VHPOSR */
-    SW (0);                    /* 008 DSKDATR */
-    SW (JOY0DAT());            /* 00A JOY0DAT */
-    SW (JOY1DAT());            /* 00C JOY1DAT */
-    SW (clxdat);               /* 00E CLXDAT */
-    SW (ADKCONR());            /* 010 ADKCONR */
-    SW (POT0DAT());            /* 012 POT0DAT */
-    SW (POT0DAT());            /* 014 POT1DAT */
-    SW (0)     ;               /* 016 POTINP * */
-    SW (0);                    /* 018 SERDATR * */
-    SW (dskbytr);              /* 01A DSKBYTR */
-    SW (INTENAR());            /* 01C INTENAR */
-    SW (INTREQR());            /* 01E INTREQR */
-    SL (dskpt);                        /* 020-023 DSKPT */
-    SW (dsklen);               /* 024 DSKLEN */
-    SW (0);                    /* 026 DSKDAT */
-    SW (0);                    /* 028 REFPTR */
-    SW (lof);                  /* 02A VPOSW */
-    SW (0);                    /* 02C VHPOSW */
-    SW (copcon);               /* 02E COPCON */
-    SW (serper);               /* 030 SERDAT * */
-    SW (serdat);               /* 032 SERPER * */
-    SW (potgo_value);          /* 034 POTGO */
-    SW (0);                    /* 036 JOYTEST * */
-    SW (0);                    /* 038 STREQU */
-    SW (0);                    /* 03A STRVBL */
-    SW (0);                    /* 03C STRHOR */
-    SW (0);                    /* 03E STRLONG */
-    SW (bltcon0);              /* 040 BLTCON0 */
-    SW (bltcon1);              /* 042 BLTCON1 */
-    SW (blt_info.bltafwm);     /* 044 BLTAFWM */
-    SW (blt_info.bltalwm);     /* 046 BLTALWM */
-    SL (bltcpt);               /* 048-04B BLTCPT */
-    SL (bltbpt);               /* 04C-04F BLTCPT */
-    SL (bltapt);               /* 050-053 BLTCPT */
-    SL (bltdpt);               /* 054-057 BLTCPT */
-    SW (0);                    /* 058 BLTSIZE */
-    SW (0);                    /* 05A BLTCON0L (use BLTCON0 instead) */
-    SW (blt_info.vblitsize);   /* 05C BLTSIZV */
-    SW (blt_info.hblitsize);   /* 05E BLTSIZH */
-    SW (blt_info.bltcmod);     /* 060 BLTCMOD */
-    SW (blt_info.bltbmod);     /* 062 BLTBMOD */
-    SW (blt_info.bltamod);     /* 064 BLTAMOD */
-    SW (blt_info.bltdmod);     /* 066 BLTDMOD */
-    SW (0);                    /* 068 ? */
-    SW (0);                    /* 06A ? */
-    SW (0);                    /* 06C ? */
-    SW (0);                    /* 06E ? */
-    SW (blt_info.bltcdat);     /* 070 BLTCDAT */
-    SW (blt_info.bltbdat);     /* 072 BLTBDAT */
-    SW (blt_info.bltadat);     /* 074 BLTADAT */
-    SW (0);                    /* 076 ? */
-    SW (0);                    /* 078 ? */
-    SW (0);                    /* 07A ? */
-    SW (DENISEID());           /* 07C DENISEID/LISAID */
-    SW (dsksync);              /* 07E DSKSYNC */
-    SL (cop1lc);               /* 080-083 COP1LC */
-    SL (cop2lc);               /* 084-087 COP2LC */
-    SW (0);                    /* 088 ? */
-    SW (0);                    /* 08A ? */
-    SW (0);                    /* 08C ? */
-    SW (diwstrt);              /* 08E DIWSTRT */
-    SW (diwstop);              /* 090 DIWSTOP */
-    SW (ddfstrt);              /* 092 DDFSTRT */
-    SW (ddfstop);              /* 094 DDFSTOP */
-    SW (dmacon);               /* 096 DMACON */
-    SW (clxcon);               /* 098 CLXCON */
-    SW (intena);               /* 09A INTENA */
-    SW (intreq);               /* 09C INTREQ */
-    SW (adkcon);               /* 09E ADKCON */
-    for (i = 0; full && i < 32; i++)
-       SW (0);
-    for (i = 0; i < 8; i++)
-       SL (bplpt[i]);          /* 0E0-0FE BPLxPT */
-    SW (bplcon0);              /* 100 BPLCON0 */
-    SW (bplcon1);              /* 102 BPLCON1 */
-    SW (bplcon2);              /* 104 BPLCON2 */
-    SW (bplcon3);              /* 106 BPLCON3 */
-    SW (bpl1mod);              /* 108 BPL1MOD */
-    SW (bpl2mod);              /* 10A BPL2MOD */
-    SW (bplcon4);              /* 10C BPLCON4 */
-    SW (clxcon2);              /* 10E CLXCON2 */
-    for (i = 0;i < 8; i++)
-       SW (0);                 /* 110 BPLxDAT */
-    if (full) {
-       for (i = 0; i < 8; i++) {
-           SL (spr[i].pt);         /* 120-13E SPRxPT */
-           SW (sprpos[i]);         /* 1x0 SPRxPOS */
-           SW (sprctl[i]);         /* 1x2 SPRxPOS */
-           SW (sprdata[i][0]);     /* 1x4 SPRxDATA */
-           SW (sprdatb[i][0]);     /* 1x6 SPRxDATB */
-       }
-    }
-    for ( i = 0; i < 32; i++)
-       SW (current_colors.color_regs_ecs[i]); /* 180-1BE COLORxx */
-    SW (htotal);               /* 1C0 HTOTAL */
-    SW (0);                    /* 1C2 */
-    SW (0);                    /* 1C4 */
-    SW (0);                    /* 1C6 */
-    SW (vtotal);               /* 1C8 VTOTAL */
-    SW (0);                    /* 1CA */
-    SW (0);                    /* 1CC */
-    SW (0);                    /* 1CE */
-    SW (0);                    /* 1D0 */
-    SW (0);                    /* 1D2 */
-    SW (0);                    /* 1D4 */
-    SW (0);                    /* 1D6 */
-    SW (0);                    /* 1D8 */
-    SW (0);                    /* 1DA */
-    SW (beamcon0);             /* 1DC BEAMCON0 */
-    SW (0);                    /* 1DE */
-    SW (0);                    /* 1E0 */
-    SW (0);                    /* 1E2 */
-    SW (diwhigh | (diwhigh_written ? 0x8000 : 0)); /* 1E4 */
-    SW (0);                    /* 1E6 */
-    SW (0);                    /* 1E8 */
-    SW (0);                    /* 1EA */
-    SW (0);                    /* 1EC */
-    SW (0);                    /* 1EE */
-    SW (0);                    /* 1F0 */
-    SW (0);                    /* 1F2 */
-    SW (0);                    /* 1F4 */
-    SW (0);                    /* 1F6 */
-    SW (0);                    /* 1F8 */
-    SW (0);                    /* 1FA */
-    SW (fmode);                        /* 1FC FMODE */
-    SW (last_custom_value);    /* 1FE */
-
-    *len = dst - dstbak;
-    return dstbak;
-}
-
-uae_u8 *restore_custom_agacolors (uae_u8 *src)
-{
-    int i;
-
-    for (i = 0; i < 256; i++)
-#ifdef AGA
-       current_colors.color_regs_aga[i] = RL;
-#else
-       RL;
-#endif
-    return src;
-}
-
-uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr)
-{
-    uae_u8 *dstbak, *dst;
-    int i;
-
-    if (dstptr)
-       dstbak = dst = dstptr;
-    else
-        dstbak = dst = malloc (256*4);
-    for (i = 0; i < 256; i++)
-#ifdef AGA     
-    SL (current_colors.color_regs_aga[i]);
-#else
-    SL (0);
-#endif
-    *len = dst - dstbak;
-    return dstbak;
-}
-
-uae_u8 *restore_custom_sprite (int num, uae_u8 *src)
-{
-    spr[num].pt = RL;          /* 120-13E SPRxPT */
-    sprpos[num] = RW;          /* 1x0 SPRxPOS */
-    sprctl[num] = RW;          /* 1x2 SPRxPOS */
-    sprdata[num][0] = RW;      /* 1x4 SPRxDATA */
-    sprdatb[num][0] = RW;      /* 1x6 SPRxDATB */
-    sprdata[num][1] = RW;
-    sprdatb[num][1] = RW;
-    sprdata[num][2] = RW;
-    sprdatb[num][2] = RW;
-    sprdata[num][3] = RW;
-    sprdatb[num][3] = RW;
-    spr[num].armed = RB;
-    return src;
-}
-
-uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr)
-{
-    uae_u8 *dstbak, *dst;
-
-    if (dstptr)
-       dstbak = dst = dstptr;
-    else
-        dstbak = dst = malloc (25);
-    SL (spr[num].pt);          /* 120-13E SPRxPT */
-    SW (sprpos[num]);          /* 1x0 SPRxPOS */
-    SW (sprctl[num]);          /* 1x2 SPRxPOS */
-    SW (sprdata[num][0]);      /* 1x4 SPRxDATA */
-    SW (sprdatb[num][0]);      /* 1x6 SPRxDATB */
-    SW (sprdata[num][1]);
-    SW (sprdatb[num][1]);
-    SW (sprdata[num][2]);
-    SW (sprdatb[num][2]);
-    SW (sprdata[num][3]);
-    SW (sprdatb[num][3]);
-    SB (spr[num].armed ? 1 : 0);
-    *len = dst - dstbak;
-    return dstbak;
-}
-
-void check_prefs_changed_custom (void)
-{
-    currprefs.gfx_framerate = changed_prefs.gfx_framerate;
-    if (inputdevice_config_change_test ()) {
-       inputdevice_copyconfig (&changed_prefs, &currprefs);
-       inputdevice_updateconfig (&currprefs);
-    }
-    currprefs.immediate_blits = changed_prefs.immediate_blits;
-    currprefs.collision_level = changed_prefs.collision_level;
-    currprefs.fast_copper = changed_prefs.fast_copper;
-
-    if (currprefs.chipset_mask != changed_prefs.chipset_mask ||
-       currprefs.gfx_vsync != changed_prefs.gfx_vsync ||
-       currprefs.ntscmode != changed_prefs.ntscmode) {
-       currprefs.gfx_vsync = changed_prefs.gfx_vsync;
-       currprefs.chipset_mask = changed_prefs.chipset_mask;
-       if (currprefs.ntscmode != changed_prefs.ntscmode) {
-           currprefs.ntscmode = changed_prefs.ntscmode;
-           new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
-       }
-       init_hz ();
-       calcdiw ();
-    }
-    currprefs.gfx_filter_horiz_zoom = changed_prefs.gfx_filter_horiz_zoom;
-    currprefs.gfx_filter_vert_zoom = changed_prefs.gfx_filter_vert_zoom;
-    currprefs.gfx_filter_horiz_offset = changed_prefs.gfx_filter_horiz_offset;
-    currprefs.gfx_filter_vert_offset = changed_prefs.gfx_filter_vert_offset;
-    currprefs.gfx_filter_scanlines = changed_prefs.gfx_filter_scanlines;
-    currprefs.gfx_filter_filtermode = changed_prefs.gfx_filter_filtermode;
-}
-
-#ifdef CPUEMU_6
-
-STATIC_INLINE void sync_copper (int hpos)
-{
-    if (eventtab[ev_copper].active) {
-       eventtab[ev_copper].active = 0;
-       update_copper (hpos);
-       return;
-    }
-    if (copper_enabled_thisline)
-       update_copper (hpos);
-}
-
-STATIC_INLINE int dma_cycle(void)
-{
-    int hpos, cycles = 0, bnasty = 0;
-
-    for (;;) {
-       int bpldma;
-       int blitpri = dmaen (DMA_BLITPRI);
-        do_cycles (1 * CYCLE_UNIT);
-       cycles += CYCLE_UNIT;
-        hpos = current_hpos ();
-       sync_copper (hpos);
-       decide_line (hpos);
-       bpldma = is_bitplane_dma (hpos);
-       if (cycle_line[hpos] == 0 && !bpldma) {
-           if (bltstate == BLT_done || bnasty >= 3)
-               break;
-           decide_blitter (hpos);
-           if (cycle_line[hpos] == 0)
-               break;
-           if (!blitpri || blit_singlechannel)
-               bnasty++;
-       } else if (bpldma && (blit_singlechannel || !blitpri)) {
-           bnasty++;
-       }
-       /* bus was allocated to dma channel, wait for next cycle.. */
-    }
-    cycle_line[hpos] |= CYCLE_CPU;
-    return cycles;
-}
-
-uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
-{
-    uae_u32 v = 0;
-    dma_cycle ();
-    if (mode > 0)
-       v = get_word (addr);
-    else if (mode == 0)
-       v = get_byte (addr);
-    do_cycles (1 * CYCLE_UNIT);
-    return v;
-}
-
-uae_u32 wait_cpu_cycle_read_cycles (uaecptr addr, int mode, int *cycles)
-{
-    uae_u32 v = 0;
-    *cycles = dma_cycle () + CYCLE_UNIT;
-    if (mode > 0)
-       v = get_word (addr);
-    else if (mode == 0)
-       v = get_byte (addr);
-    do_cycles (1 * CYCLE_UNIT);
-    return v;
-}
-
-void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
-{
-    dma_cycle ();
-    if (mode > 0)
-       put_word (addr, v);
-    else if (mode == 0)
-       put_byte (addr, v);
-    do_cycles (1 * CYCLE_UNIT);
-}
-
-void do_cycles_ce (long cycles)
-{
-    int hpos, bpldma;
-    while (cycles > 0) {
-        do_cycles (1 * CYCLE_UNIT);
-       cycles -= CYCLE_UNIT;
-        hpos = current_hpos ();
-       sync_copper (hpos);
-       decide_line (hpos);
-       bpldma = is_bitplane_dma (hpos);
-       if (cycle_line[hpos] == 0 && !bpldma)
-           decide_blitter (hpos);
-    }
-}
-
-#endif
diff --git a/debug.c b/debug.c
index 30104e6dee95478c081942992e80d97e66dc9013..0c6a7515e976df240f8f07fce9310b19be8656af 100755 (executable)
--- a/debug.c
+++ b/debug.c
@@ -30,6 +30,7 @@
 #include "disk.h"
 #include "savestate.h"
 #include "autoconf.h"
+#include "akiko.h"
 
 static int debugger_active;
 static uaecptr skipaddr_start, skipaddr_end, skipaddr_doskip;
@@ -94,9 +95,10 @@ static char help[] = {
     "  W <address> <value>   Write into Amiga memory\n"
     "  w <num> <address> <length> <R/W/RW> [<value>]\n"
     "                        Add/remove memory watchpoints\n"
+    "  wd                    Enable illegal access logger\n"
     "  S <file> <addr> <n>   Save a block of Amiga memory\n"
     "  s <string>/<values> [<addr>] [<length>]\n"
-    "                        search for string/bytes\n"
+    "                        Search for string/bytes\n"
     "  T                     Show exec tasks and their PCs\n"
     "  h,?                   Show this help page\n"
     "  b                     Step to previous state capture position\n"
@@ -538,6 +540,86 @@ struct memwatch_node {
 static struct memwatch_node mwnodes[MEMWATCH_TOTAL];
 static struct memwatch_node mwhit;
 
+static uae_u8 *illgdebug;
+extern int cdtv_enabled, cd32_enabled;
+
+static void illg_init (void)
+{
+    int i;
+
+    free (illgdebug);
+    illgdebug = xmalloc (0x1000000);
+    if (!illgdebug)
+       return;
+    memset (illgdebug, 3, 0x1000000);
+    memset (illgdebug, 0, currprefs.chipmem_size);
+    memset (illgdebug + 0xc00000, 0, currprefs.bogomem_size);
+    memset (illgdebug + 0x200000, 0, currprefs.fastmem_size);
+    i = 0;
+    while (custd[i].name) {
+       int rw = custd[i].rw;
+       illgdebug[custd[i].adr] = rw;
+       illgdebug[custd[i].adr + 1] = rw;
+       i++;
+    }
+    for (i = 0; i < 16; i++) { /* CIAs */
+       if (i == 11)
+           continue;
+       illgdebug[0xbfe001 + i * 0x100] = 0;
+       illgdebug[0xbfd000 + i * 0x100] = 0;
+    }
+    memset (illgdebug + 0xf80000, 1, 512 * 1024); /* KS ROM */
+    memset (illgdebug + 0xdc0000, 0, 0x3f); /* clock */
+    if (cdtv_enabled) {
+       memset (illgdebug + 0xf00000, 1, 256 * 1024); /* CDTV ext ROM */
+       memset (illgdebug + 0xdc8000, 0, 4096); /* CDTV batt RAM */
+    }
+    if (cd32_enabled || cloanto_rom) {
+       memset (illgdebug + 0xe00000, 1, 512 * 1024); /* CD32 ext ROM */
+       if (cd32_enabled)
+           memset (illgdebug + AKIKO_BASE, 0, AKIKO_BASE_END - AKIKO_BASE);
+    }
+    if (nr_units (currprefs.mountinfo) > 0) /* filesys "rom" */
+       memset (illgdebug + RTAREA_BASE, 1, 0x10000);
+}
+
+/* add special custom register check here */
+static void illg_debug_check (uaecptr addr, int rw, int size, uae_u32 val)
+{
+    return;
+}
+
+static void illg_debug_do (uaecptr addr, int rw, int size, uae_u32 val)
+{
+    uae_u8 mask;
+    uae_u32 pc = m68k_getpc ();
+    char rws = rw ? 'W' : 'R';
+    int i;
+
+    for (i = size - 1; i >= 0; i--) {
+       uae_u8 v = val >> (i * 8);
+       uae_u32 ad = addr + i;
+       if (ad >= 0x1000000)
+           mask = 3;
+       else
+           mask = illgdebug[ad];
+       if (!mask)
+           continue;
+       if (mask & 0x80) {
+           illg_debug_check (ad, rw, size, val);
+       } else if ((mask & 3) == 3) {
+           if (rw)
+               write_log ("RW: %08.8X=%02.2X %c PC=%08.8X\n", ad, v, rws, pc);
+           else
+               write_log ("RW: %08.8X    %c PC=%08.8X\n", ad, rws, pc);
+       } else if ((mask & 1) && rw) {
+           write_log ("RO: %08.8X=%02.2X %c PC=%08.8X\n", ad, v, rws, pc);
+       } else if ((mask & 2) && !rw) {
+           write_log ("WO: %08.8X    %c PC=%08.8X\n", ad, rws, pc);
+       }
+    }
+}
+
 static int debug_mem_off (uaecptr addr)
 {
     return (munge24 (addr) >> 16) & 0xff;
@@ -547,6 +629,8 @@ static void memwatch_func (uaecptr addr, int rw, int size, uae_u32 val)
 {
     int i, brk;
 
+    if (illgdebug)
+       illg_debug_do (addr, rw, size, val);
     addr = munge24 (addr);
     for (i = 0; i < MEMWATCH_TOTAL; i++) {
        uaecptr addr2 = mwnodes[i].addr;
@@ -659,6 +743,8 @@ static void deinitialize_memwatch (void)
     free (debug_mem_banks);
     debug_mem_banks = 0;
     memwatch_enabled = 0;
+    free (illgdebug);
+    illgdebug = 0;
 }
 
 static int initialize_memwatch (void)
@@ -735,6 +821,28 @@ static void memwatch (char **c)
        console_out ("Memwatch breakpoints disabled\n");
        return;
     }
+    if (nc == 'd') {
+       if (illgdebug) {
+           ignore_ws (c);
+           if (more_params (c)) {
+               uae_u32 addr = readhex (c);
+               uae_u32 len = 1;
+               if (more_params (c))
+                   len = readhex (c);
+               write_log ("cleared logging addresses %08.8X - %08.8X\n", addr, addr + len);
+               while (len > 0) {
+                   addr &= 0xffffff;
+                   illgdebug[addr] = 0;
+                   addr++;
+                   len--;
+               }
+           }
+       } else {
+           illg_init ();
+           console_out ("Illegal memory access logging enabled\n");
+       }
+       return;
+    }
     num = nc - '0';
     if (num < 0 || num >= MEMWATCH_TOTAL)
        return;
index 433de9959246195438849333d342efccae8aa80d..854373acd1486ce44880b9c75fab7cd54e50535c 100755 (executable)
--- a/drawing.c
+++ b/drawing.c
@@ -141,12 +141,12 @@ static char linestate[(MAXVPOS + 1)*2 + 1];
 uae_u8 line_data[(MAXVPOS + 1) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2];
 
 /* Centering variables.  */
-static int min_diwstart, max_diwstop, prev_x_adjust;
+static int min_diwstart, max_diwstop;
 /* The visible window: VISIBLE_LEFT_BORDER contains the left border of the visible
    area, VISIBLE_RIGHT_BORDER the right border.  These are in window coordinates.  */
 static int visible_left_border, visible_right_border;
 static int linetoscr_x_adjust_bytes;
-static int thisframe_y_adjust, prev_y_adjust;
+static int thisframe_y_adjust;
 static int thisframe_y_adjust_real, max_ypos_thisframe, min_ypos_for_screen;
 static int extra_y_adjust;
 int thisframe_first_drawn_line, thisframe_last_drawn_line;
@@ -1526,8 +1526,8 @@ STATIC_INLINE void pfield_draw_line (int lineno, int gfx_ypos, int follow_ypos)
 
 static void center_image (void)
 {
-    prev_x_adjust = visible_left_border;
-    prev_y_adjust = thisframe_y_adjust;
+    int prev_x_adjust = visible_left_border;
+    int prev_y_adjust = thisframe_y_adjust;
 
     if (currprefs.gfx_xcenter) {
 
@@ -1540,7 +1540,7 @@ static void center_image (void)
        /* Would the old value be good enough? If so, leave it as it is if we want to
         * be clever. */
        if (currprefs.gfx_xcenter == 2) {
-           if (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart)
+           if (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32)
                visible_left_border = prev_x_adjust;
        }
     } else
diff --git a/fdi2raw2.c b/fdi2raw2.c
deleted file mode 100755 (executable)
index 3c2dc19..0000000
+++ /dev/null
@@ -1,1986 +0,0 @@
-/*
-
-  FDI to raw bit stream        converter
-  Copyright (c)        2001 by Toni Wilen <twilen@arabuusimiehet.com>
-  FDI 2.0 support
-  Copyright (c)        2003-2004 by Toni Wilen <twilen@arabuusimiehet.com>
-                   and Vincent Joguin
-
-  FDI format created by        Vincent "ApH" Joguin
-
-  Tiny changes - function type fixes, multiple drives, addition        of
-  get_last_head        and C++ callability - by Thomas Harte, 2001,
-  T.Harte@excite.co.uk
-
-
-  This program is free software; you can redistribute it and/or        modify it
-  under        the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2        of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY;        without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A        PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.        
-
-  You should have received a copy of the GNU General Public License along
-  with this program; if        not, write to the Free Software Foundation, Inc.,
-  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* IF UAE */
-#include "sysconfig.h"
-#include "sysdeps.h"
-#include "zfile.h"
-/* ELSE        */
-//#include "types.h"
-
-#include "fdi2raw.h"
-
-#undef DEBUG
-#define VERBOSE        
-//#undef VERBOSE
-
-#include <assert.h>
-
-#ifdef DEBUG
-static char *datalog(uae_u8 *src, int len)
-{
-       static char buf[1000];
-       static int offset;
-       int i = 0, offset2;
-
-       offset2 = offset;
-       buf[offset++]='\'';
-       while(len--) {
-               sprintf (buf + offset, "%02.2X", src[i]);
-               offset += 2;
-               i++;
-               if (i > 10) break;
-       }
-       buf[offset++]='\'';
-       buf[offset++] = 0;
-       if (offset >= 900) offset = 0;
-       return buf + offset2;
-}
-#else
-static char *datalog(uae_u8 *src, int len) { return "";        }
-#endif
-
-#ifdef DEBUG
-#define        debuglog write_log
-#else
-#define        debuglog
-#endif
-#ifdef VERBOSE
-#define        outlog write_log
-#else
-#define        outlog
-#endif
-
-static int fdi_allocated;
-#ifdef DEBUG
-static void fdi_free (void *p)
-{
-       int size;
-       if (!p) 
-               return; 
-       size = ((int*)p)[-1];
-       fdi_allocated -= size;
-       write_log ("%d freed (%d)\n", size, fdi_allocated);
-       free ((int*)p - 1);
-}
-static void *fdi_malloc        (int size)
-{
-       void *p = xmalloc (size + sizeof (int));
-       ((int*)p)[0] = size;
-       fdi_allocated += size;
-       write_log ("%d allocated (%d)\n", size, fdi_allocated); 
-       return (int*)p + 1;
-}
-#else
-#define        fdi_free free
-#define        fdi_malloc xmalloc
-#endif
-
-#define        MAX_SRC_BUFFER 4194304
-#define        MAX_DST_BUFFER 40000
-#define        MAX_MFM_SYNC_BUFFER 60000
-#define        MAX_TIMING_BUFFER 400000
-#define        MAX_TRACKS 166
-
-struct fdi_cache {
-       uae_u32 *avgp, *minp, *maxp;
-       uae_u8 *idxp;
-       int avg_free, idx_free, min_free, max_free;
-       uae_u32 totalavg, pulses, maxidx, indexoffset;
-       int weakbits;
-       int lowlevel;
-};
-
-struct fdi {
-       uae_u8 *track_src_buffer;
-       uae_u8 *track_src;
-       int track_src_len;
-       uae_u8 *track_dst_buffer;
-       uae_u8 *track_dst;
-       uae_u16 *track_dst_buffer_timing;
-       uae_u8 track_len;
-       uae_u8 track_type;
-       int current_track;
-       int last_track; 
-       int last_head;
-       int rotation_speed;
-       int bit_rate;
-       int disk_type;
-       int write_protect;
-       int err;
-       uae_u8 header[2048];
-       int track_offsets[MAX_TRACKS];
-       struct zfile *file;
-       int out;
-       int mfmsync_offset;
-       int *mfmsync_buffer;
-       /* sector described only */
-       int index_offset;
-       int encoding_type;
-       /* bit handling */
-       int nextdrop;
-       struct fdi_cache cache[MAX_TRACKS];
-};
-
-#define        get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3]))
-#define        get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2]))
-STATIC_INLINE put_u32 (uae_u8 *d, uae_u32 v)
-{
-       d[0] = v >> 24; 
-       d[1] = v >> 16; 
-       d[2] = v >> 8;
-       d[3] = v;
-}
-
-struct node {
-       uae_u16 v;
-       struct node *left;
-       struct node *right;
-};
-typedef        struct node NODE;
-
-static uae_u8 temp, temp2;
-
-static uae_u8 *expand_tree (uae_u8 *stream, NODE *node)        
-{
-       if (temp & temp2) {
-               fdi_free (node->left);
-               node->left = 0; 
-               fdi_free (node->right); 
-               node->right = 0;
-               temp2 >>= 1;
-               if (!temp2) {
-                       temp = *stream++;
-                       temp2 = 0x80;
-               }
-               return stream;
-       } else {
-               uae_u8 *stream_temp;
-               temp2 >>= 1;
-               if (!temp2) {
-                       temp = *stream++;
-                       temp2 = 0x80;
-               }
-               node->left = fdi_malloc (sizeof (NODE));
-               memset (node->left, 0, sizeof (NODE));
-               stream_temp = expand_tree (stream, node->left); 
-               node->right = fdi_malloc (sizeof (NODE));
-               memset (node->right, 0, sizeof (NODE)); 
-               return expand_tree (stream_temp, node->right);
-       }
-}
-
-static uae_u8 *values_tree8 (uae_u8 *stream, NODE *node)
-{
-       if (node->left == 0) {
-               node->v = *stream++;
-               return stream;
-       } else {
-               uae_u8 *stream_temp = values_tree8 (stream, node->left);
-               return values_tree8 (stream_temp, node->right); 
-       }
-}
-
-static uae_u8 *values_tree16 (uae_u8 *stream, NODE *node)
-{
-       if (node->left == 0) {
-               uae_u16 high_8_bits = (*stream++) << 8; 
-               node->v = high_8_bits | (*stream++);
-               return stream;
-       } else {
-               uae_u8 *stream_temp = values_tree16 (stream, node->left);
-               return values_tree16 (stream_temp, node->right);
-       }
-}
-
-static void free_nodes (NODE *node)
-{
-       if (node) {
-               free_nodes (node->left);
-               free_nodes (node->right);
-               fdi_free (node);
-       }
-}
-
-static uae_u32 sign_extend16 (uae_u32 v)
-{
-       if (v & 0x8000) 
-               v |= 0xffff0000;
-       return v;
-}
-
-static uae_u32 sign_extend8 (uae_u32 v)        
-{
-       if (v & 0x80)
-               v |= 0xffffff00;
-       return v;
-}
-
-static void fdi_decode (uae_u8 *stream,        int size, uae_u8 *out)
-{
-       int i;
-       uae_u8 sign_extend, sixteen_bit, sub_stream_shift;
-       NODE root;
-       NODE *current_node;
-
-       memset (out, 0, size * 4);
-       sub_stream_shift = 1;
-       while (sub_stream_shift) {
-
-               //sub-stream header decode
-               sign_extend = *stream++;
-               sub_stream_shift = sign_extend & 0x7f;
-               sign_extend &= 0x80;
-               sixteen_bit = (*stream++) & 0x80;
-
-               //huffman tree architecture decode
-               temp = *stream++;
-               temp2 = 0x80;
-               stream = expand_tree (stream, &root);
-               if (temp2 == 0x80)
-                       stream--;
-
-               //huffman output values decode
-               if (sixteen_bit)
-                       stream = values_tree16 (stream, &root); 
-               else
-                       stream = values_tree8 (stream, &root);
-
-               //sub-stream data decode
-               temp2 = 0;
-               for (i = 0; i < size; i++) {
-                       uae_u32 v;
-                       uae_u8 decode = 1;
-                       current_node = &root;
-                       while (decode) {
-                               if (current_node->left == 0) {
-                                       decode = 0;
-                               } else {
-                                       temp2 >>= 1;
-                                       if (!temp2) {
-                                               temp2 = 0x80;
-                                               temp = *stream++;
-                                       }
-                                       if (temp & temp2)
-                                               current_node = current_node->right;
-                                       else
-                                               current_node = current_node->left;
-                               }
-                       }
-                       v = ((uae_u32*)out)[i]; 
-                       if (sign_extend) {
-                               if (sixteen_bit)
-                                       v |= sign_extend16 (current_node->v) << sub_stream_shift;
-                               else
-                                       v |= sign_extend8 (current_node->v) << sub_stream_shift;
-                       } else {
-                               v |= current_node->v << sub_stream_shift;
-                       }
-                       ((uae_u32*)out)[i] = v; 
-               }
-               free_nodes (root.left); 
-               free_nodes (root.right);
-       }
-}
-
-
-static int decode_raw_track (FDI *fdi)
-{
-       int size = get_u32(fdi->track_src);
-       memcpy (fdi->track_dst, fdi->track_src, (size + 7) >> 3);
-       fdi->track_src += (size + 7) >> 3;
-       return size;
-}
-
-/* unknown track */
-static void zxx        (FDI *fdi)
-{
-       outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-//     return -1;
-}
-/* unsupported track */        
-static void zyy        (FDI *fdi)
-{
-       outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-//     return -1;
-}
-/* empty track */
-static void track_empty        (FDI *fdi)
-{
-//     return 0;
-}
-
-/* unknown sector described type */
-static void dxx        (FDI *fdi)
-{
-       outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-       fdi->err = 1;
-}
-/* unsupported sector described        type */ 
-static void dyy        (FDI *fdi)
-{
-       outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type);
-       fdi->err = 1;
-}
-/* add position        of mfm sync bit */
-static void add_mfm_sync_bit (FDI *fdi)        
-{
-       if (fdi->nextdrop) {
-               fdi->nextdrop = 0;
-               return; 
-       }
-       fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out;
-       if (fdi->out == 0) {
-               outlog ("illegal position for mfm sync bit, offset=%d\n",fdi->out);
-               fdi->err = 1;
-       }
-       if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) {
-               fdi->mfmsync_offset = 0;
-               outlog ("mfmsync buffer overflow\n");
-               fdi->err = 1;
-       }
-       fdi->out++;
-}
-
-#define        BIT_BYTEOFFSET ((fdi->out) >> 3)
-#define        BIT_BITOFFSET (7-((fdi->out)&7))
-
-/* add one bit */
-static void bit_add (FDI *fdi, int bit)        
-{
-       if (fdi->nextdrop) {
-               fdi->nextdrop = 0;
-               return; 
-       }
-       fdi->track_dst[BIT_BYTEOFFSET] &= ~(1 << BIT_BITOFFSET);
-       if (bit) 
-               fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET); 
-       fdi->out++;
-       if (fdi->out >= MAX_DST_BUFFER * 8) {
-               outlog ("destination buffer overflow\n");
-               fdi->err = 1;
-               fdi->out = 1;
-       }
-}
-/* add bit and mfm sync        bit */
-static void bit_mfm_add        (FDI *fdi, int bit)
-{
-       add_mfm_sync_bit (fdi); 
-       bit_add (fdi, bit);
-}
-/* remove following bit        */
-static void bit_drop_next (FDI *fdi)
-{
-       if (fdi->nextdrop > 0) {
-               outlog("multiple bit_drop_next() called");
-       } else if (fdi->nextdrop < 0) { 
-               fdi->nextdrop = 0;
-               debuglog(":DNN:");
-               return; 
-       }
-       debuglog(":DN:");
-       fdi->nextdrop = 1;
-}
-
-/* ignore next bit_drop_next() */
-static void bit_dedrop (FDI *fdi)
-{
-       if (fdi->nextdrop) {
-               outlog("bit_drop_next called before bit_dedrop");
-       }
-       fdi->nextdrop = -1;
-       debuglog(":BDD:");
-}
-
-/* add one byte        */
-static void byte_add (FDI *fdi,        uae_u8 v)
-{
-       int i;
-       for (i = 7; i >= 0; i--)
-               bit_add (fdi, v & (1 << i));
-}
-/* add one word        */
-static void word_add (FDI *fdi,        uae_u16 v)
-{
-       byte_add (fdi, (uae_u8)(v >> 8));
-       byte_add (fdi, (uae_u8)v);
-}
-/* add one byte        and mfm encode it */
-static void byte_mfm_add (FDI *fdi, uae_u8 v)
-{
-       int i;
-       for (i = 7; i >= 0; i--)
-               bit_mfm_add (fdi, v & (1 << i));
-}
-/* add multiple        bytes and mfm encode them */
-static void bytes_mfm_add (FDI *fdi, uae_u8 v, int len)        
-{
-       int i;
-       for (i = 0; i < len; i++) byte_mfm_add (fdi, v);
-}
-/* add one mfm encoded word and        re-mfm encode it */
-static void word_post_mfm_add (FDI *fdi, uae_u16 v)
-{
-       int i;
-       for (i = 14; i >= 0; i -= 2)
-               bit_mfm_add (fdi, v & (1 << i));
-}
-
-/* bit 0 */
-static void s00(FDI *fdi) { bit_add (fdi, 0); }        
-/* bit 1*/
-static void s01(FDI *fdi) { bit_add (fdi, 1); }        
-/* 4489        */
-static void s02(FDI *fdi) { word_add (fdi, 0x4489); }
-/* 5224        */
-static void s03(FDI *fdi) { word_add (fdi, 0x5224); }
-/* mfm sync bit        */
-static void s04(FDI *fdi) { add_mfm_sync_bit (fdi); }
-/* RLE MFM-encoded data        */
-static void s08(FDI *fdi)
-{
-       int bytes = *fdi->track_src++;
-       uae_u8 byte = *fdi->track_src++;
-       if (bytes == 0) bytes = 256;
-       debuglog ("s08:len=%d,data=%02.2X",bytes,byte); 
-       while(bytes--) byte_add (fdi, byte);
-}
-/* RLE MFM-decoded data        */
-static void s09(FDI *fdi)
-{
-       int bytes = *fdi->track_src++;
-       uae_u8 byte = *fdi->track_src++;
-       if (bytes == 0) bytes = 256;
-       bit_drop_next (fdi);
-       debuglog ("s09:len=%d,data=%02.2X",bytes,byte); 
-       while(bytes--) byte_mfm_add (fdi, byte);
-}
-/* MFM-encoded data */
-static void s0a(FDI *fdi)
-{
-       int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
-       uae_u8 b;
-       fdi->track_src += 2;
-       debuglog ("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) { 
-               i = 7;
-               b = *fdi->track_src++;
-               while (bits--) {
-                       bit_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-encoded data */
-static void s0b(FDI *fdi)
-{
-       int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
-       uae_u8 b;
-       fdi->track_src += 2;
-       debuglog ("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) { 
-               i = 7;
-               b = *fdi->track_src++;
-               while (bits--) {
-                       bit_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-decoded data */
-static void s0c(FDI *fdi)
-{
-       int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
-       uae_u8 b;
-       fdi->track_src += 2;
-       bit_drop_next (fdi);
-       debuglog ("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_mfm_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) { 
-               i = 7;
-               b = *fdi->track_src++;
-               while(bits--) { 
-                       bit_mfm_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-decoded data */
-static void s0d(FDI *fdi)
-{
-       int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
-       uae_u8 b;
-       fdi->track_src += 2;
-       bit_drop_next (fdi);
-       debuglog ("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_mfm_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) { 
-               i = 7;
-               b = *fdi->track_src++;
-               while(bits--) { 
-                       bit_mfm_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-
-/* ***** */
-/* AMIGA */
-/* ***** */
-
-/* just        for testing integrity of Amiga sectors */
-
-static void rotateonebit (uae_u8 *start, uae_u8        *end, int shift)
-{
-       if (shift == 0) 
-               return; 
-       while (start <= end) {
-               start[0] <<= shift;
-               start[0] |= start[1] >> (8 - shift);
-               start++;
-       }
-}
-
-static int check_offset;
-static uae_u16 getmfmword (uae_u8 *mbuf)
-{
-       uae_u32 v;
-
-       v = (mbuf[0] << 8) | (mbuf[1] << 0);
-       if (check_offset == 0)
-               return v;
-       v <<= 8;
-       v |= mbuf[2];
-       v >>= check_offset;
-       return v;
-}
-
-#define        MFMMASK 0x55555555
-static uae_u32 getmfmlong (uae_u8 * mbuf)
-{
-       return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK;
-}
-
-static int amiga_check_track (FDI *fdi)        
-{
-       int i, j, secwritten = 0;
-       int fwlen = fdi->out / 8;
-       int length = 2 * fwlen; 
-       int drvsec = 11;
-       uae_u32 odd, even, chksum, id, dlong;
-       uae_u8 *secdata;
-       uae_u8 secbuf[544];
-       uae_u8 bigmfmbuf[60000];
-       uae_u8 *mbuf, *mbuf2, *mend;
-       char sectable[22];
-       uae_u8 *raw = fdi->track_dst_buffer;
-       int slabel, off;
-       int ok = 1;
-
-       memset (bigmfmbuf, 0, sizeof (bigmfmbuf));
-       mbuf = bigmfmbuf;
-       check_offset = 0;
-       for (i = 0; i < (fdi->out + 7) / 8; i++)
-               *mbuf++ = raw[i];
-       off = fdi->out & 7;
-#if 1
-       if (off > 0) {
-               mbuf--; 
-               *mbuf &= ~((1 << (8 - off)) - 1);
-       }
-       j = 0;
-       while (i < (fdi->out + 7) / 8 + 600) {
-               *mbuf++ |= (raw[j] >> off) | ((raw[j + 1]) << (8 - off));
-               j++;
-               i++;
-       }
-#endif
-       mbuf = bigmfmbuf;
-
-       memset (sectable, 0, sizeof (sectable));
-       //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof (uae_u16));
-       mend = bigmfmbuf + length;
-       mend -= (4 + 16 + 8 + 512);
-
-       while (secwritten < drvsec) {
-               int trackoffs;
-
-               for (;;) {
-                       rotateonebit (bigmfmbuf, mend, 1);
-                       if (getmfmword (mbuf) == 0)
-                               break;
-                       if (secwritten == 10) { 
-                               mbuf[0] = 0x44; 
-                               mbuf[1] = 0x89; 
-                       }
-//                     check_offset++; 
-                       if (check_offset > 7) { 
-                               check_offset = 0;
-                               mbuf++; 
-                               if (mbuf >= mend || *mbuf == 0) 
-                                       break;
-                       }
-                       if (getmfmword (mbuf) == 0x4489)
-                               break;
-               }
-               if (mbuf >= mend || *mbuf == 0) 
-                       break;
-
-               rotateonebit (bigmfmbuf, mend, check_offset);
-               check_offset = 0;
-
-               while (getmfmword (mbuf) == 0x4489)
-                       mbuf+= 1 * 2;
-               mbuf2 = mbuf + 8;
-
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               id = (odd << 1) | even; 
-
-               trackoffs = (id & 0xff00) >> 8; 
-               if (trackoffs + 1 > drvsec) {
-                       outlog("illegal sector offset %d\n",trackoffs);
-                       ok = 0; 
-                       mbuf = mbuf2;
-                       continue;
-               }
-               if ((id >> 24) != 0xff) {
-                       outlog ("sector %d format type %02.2X?\n", trackoffs, id >> 24);
-                       ok = 0; 
-               }
-               chksum = odd ^ even;
-               slabel = 0;
-               for (i = 0; i < 4; i++) {
-                       odd = getmfmlong (mbuf);
-                       even = getmfmlong (mbuf + 8 * 2);
-                       mbuf += 2* 2;
-
-                       dlong = (odd << 1) | even;
-                       if (dlong) slabel = 1;
-                       chksum ^= odd ^ even;
-               }
-               mbuf += 8 * 2;
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               if (((odd << 1) | even) != chksum) {
-                       outlog("sector %d header crc error\n", trackoffs);
-                       ok = 0; 
-                       mbuf = mbuf2;
-                       continue;
-               }
-               outlog("sector %d header crc ok\n", trackoffs);
-               if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) { 
-                       outlog("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000)   >> 16); 
-                       ok++;
-                       mbuf = mbuf2;
-                       continue;
-               }
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               chksum = (odd << 1) | even;
-               secdata = secbuf + 32;
-               for (i = 0; i < 128; i++) {
-                       odd = getmfmlong (mbuf);
-                       even = getmfmlong (mbuf + 256 * 2);
-                       mbuf += 2 * 2;
-                       dlong = (odd << 1) | even;
-                       *secdata++ = (uae_u8) (dlong >> 24);
-                       *secdata++ = (uae_u8) (dlong >> 16);
-                       *secdata++ = (uae_u8) (dlong >> 8);
-                       *secdata++ = (uae_u8) dlong;
-                       chksum ^= odd ^ even;
-               }
-               mbuf += 256 * 2;
-               if (chksum) {
-                       outlog("sector %d data checksum error\n",trackoffs);
-                       ok = 0; 
-               } else if (sectable[trackoffs]) {
-                       outlog("sector %d already found?\n", trackoffs);
-                       mbuf = mbuf2;
-               } else {
-                       outlog("sector %d ok\n",trackoffs);
-                       if (slabel) outlog("(non-empty sector header)\n");
-                       sectable[trackoffs] = 1;
-                       secwritten++;
-                       if (trackoffs == 9)
-                               mbuf += 0x228;
-               }
-       }
-       for (i = 0; i < drvsec; i++) {
-               if (!sectable[i]) {
-                       outlog ("sector %d missing\n", i);
-                       ok = 0; 
-               }
-       }
-       return ok;
-}
-
-static void amiga_data_raw (FDI        *fdi, uae_u8 *secbuf, uae_u8 *crc, int len)
-{
-       int i;
-       uae_u8 crcbuf[4];
-
-       if (!crc) {
-               memset (crcbuf, 0, 4);
-       } else {
-               memcpy (crcbuf, crc ,4);
-       }
-       for (i = 0; i < 4; i++) 
-               byte_mfm_add (fdi, crcbuf[i]);
-       for (i = 0; i < len; i++)
-               byte_mfm_add (fdi, secbuf[i]);
-}
-
-static void amiga_data (FDI *fdi, uae_u8 *secbuf)
-{
-       uae_u16 mfmbuf[4 + 512];
-       uae_u32 dodd, deven, dck;
-       int i;
-
-       for (i = 0; i < 512; i += 4) {
-               deven = ((secbuf[i + 0] << 24) | (secbuf[i + 1] << 16)
-                | (secbuf[i + 2] << 8) | (secbuf[i + 3]));
-               dodd = deven >> 1;
-               deven &= 0x55555555;
-               dodd &= 0x55555555;
-               mfmbuf[(i >> 1) + 4] = (uae_u16) (dodd >> 16);
-               mfmbuf[(i >> 1) + 5] = (uae_u16) dodd;
-               mfmbuf[(i >> 1) + 256 + 4] = (uae_u16) (deven >> 16);
-               mfmbuf[(i >> 1) + 256 + 5] = (uae_u16) deven;
-       }
-       dck = 0;
-       for (i = 4; i < 4 + 512; i += 2)
-               dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-       deven = dodd = dck;
-       dodd >>= 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[0] = (uae_u16) (dodd >> 16);
-       mfmbuf[1] = (uae_u16) dodd;
-       mfmbuf[2] = (uae_u16) (deven >> 16);
-       mfmbuf[3] = (uae_u16) deven;
-
-       for (i = 0; i < 4 + 512; i ++)
-               word_post_mfm_add (fdi, mfmbuf[i]);
-}
-
-static void amiga_sector_header        (FDI *fdi, uae_u8 *header, uae_u8 *data, int sector, int untilgap)
-{
-       uae_u8 headerbuf[4], databuf[16];
-       uae_u32 deven, dodd, hck;
-       uae_u16 mfmbuf[24];
-       int i;
-
-       byte_mfm_add (fdi, 0);
-       byte_mfm_add (fdi, 0);
-       word_add (fdi, 0x4489); 
-       word_add (fdi, 0x4489); 
-       if (header) {
-               memcpy (headerbuf, header, 4);
-       } else {
-               headerbuf[0] = 0xff;
-               headerbuf[1] = (uae_u8)fdi->current_track;
-               headerbuf[2] = (uae_u8)sector;
-               headerbuf[3] = (uae_u8)untilgap;
-       }
-       if (data)
-               memcpy (databuf, data, 16);
-       else
-               memset (databuf, 0, 16);
-
-       deven = ((headerbuf[0] << 24) | (headerbuf[1] << 16)
-               | (headerbuf[2] << 8) | (headerbuf[3]));
-       dodd = deven >> 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[0] = (uae_u16) (dodd >> 16);
-       mfmbuf[1] = (uae_u16) dodd;
-       mfmbuf[2] = (uae_u16) (deven >> 16);
-       mfmbuf[3] = (uae_u16) deven;
-       for (i = 0; i < 16; i += 4) {
-               deven = ((databuf[i] << 24) | (databuf[i + 1] << 16)
-                       | (databuf[i + 2] << 8) | (databuf[i + 3]));
-               dodd = deven >> 1;
-               deven &= 0x55555555;
-               dodd &= 0x55555555;
-               mfmbuf[(i >> 1) + 0 + 4] = (uae_u16) (dodd >> 16);
-               mfmbuf[(i >> 1) + 0 + 5] = (uae_u16) dodd;
-               mfmbuf[(i >> 1) + 8 + 4] = (uae_u16) (deven >> 16);
-               mfmbuf[(i >> 1) + 8 + 5] = (uae_u16) deven;
-       }
-       hck = 0;
-       for (i = 0; i < 4 + 16; i += 2) 
-               hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-       deven = dodd = hck;
-       dodd >>= 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[20] = (uae_u16) (dodd >> 16);
-       mfmbuf[21] = (uae_u16) dodd;
-       mfmbuf[22] = (uae_u16) (deven >> 16);
-       mfmbuf[23] = (uae_u16) deven;
-
-       for (i = 0; i < 4 + 16 + 4; i ++)
-               word_post_mfm_add (fdi, mfmbuf[i]);
-}
-
-/* standard super-extended Amiga sector        header */
-static void s20(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16)); 
-       amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0);
-       fdi->track_src += 4 + 16;
-}
-/* standard extended Amiga sector header */
-static void s21(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s21:header=%s", datalog(fdi->track_src, 4)); 
-       amiga_sector_header (fdi, fdi->track_src, 0, 0, 0);
-       fdi->track_src += 4;
-}
-/* standard Amiga sector header        */
-static void s22(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
-       amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]);
-       fdi->track_src += 2;
-}
-/* standard 512-byte, CRC-correct Amiga        data */ 
-static void s23(FDI *fdi)
-{
-       debuglog("s23:data=%s", datalog (fdi->track_src, 512)); 
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-/* not-decoded,        128*2^x-byte, CRC-correct Amiga data */ 
-static void s24(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
-       amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift; 
-}
-/* not-decoded,        128*2^x-byte, CRC-incorrect Amiga data */
-static void s25(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
-       amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift); 
-       fdi->track_src += 4 + (128 << shift);
-}
-/* standard extended Amiga sector */
-static void s26(FDI *fdi)
-{
-       s21 (fdi);
-       debuglog("s26:data=%s", datalog (fdi->track_src, 512)); 
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-/* standard short Amiga        sector */
-static void s27(FDI *fdi)
-{
-       s22 (fdi);
-       debuglog("s27:data=%s", datalog (fdi->track_src, 512)); 
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-
-/* *** */
-/* IBM */
-/* *** */
-
-static uae_u16 ibm_crc (uae_u8 byte, int reset)        
-{
-       static uae_u16 crc;
-       int i;
-
-       if (reset) crc = 0xcdb4;
-       for (i = 0; i < 8; i++) {
-               if (crc & 0x8000) {
-                       crc <<= 1;
-                       if (!(byte & 0x80)) crc ^= 0x1021;
-               } else {
-                       crc <<= 1;
-                       if (byte & 0x80) crc ^= 0x1021; 
-               }
-               byte <<= 1;
-       }
-       return crc;
-}
-
-static void ibm_data (FDI *fdi,        uae_u8 *data, uae_u8 *crc, int len)
-{
-       int i;
-       uae_u8 crcbuf[2];
-       uae_u16 crcv;
-
-       word_add (fdi, 0x4489); 
-       word_add (fdi, 0x4489); 
-       word_add (fdi, 0x4489); 
-       byte_mfm_add (fdi, 0xfb);
-       ibm_crc (0xfb, 1);
-       for (i = 0; i < len; i++) {
-               byte_mfm_add (fdi, data[i]);
-               crcv = ibm_crc (data[i], 0);
-       }
-       if (!crc) {
-               crc = crcbuf;
-               crc[0] = (uae_u8)(crcv >> 8);
-               crc[1] = (uae_u8)crcv;
-       }
-       byte_mfm_add (fdi, crc[0]);
-       byte_mfm_add (fdi, crc[1]);
-}
-
-static void ibm_sector_header (FDI *fdi, uae_u8        *data, uae_u8 *crc, int secnum, int pre)
-{
-       uae_u8 secbuf[5];
-       uae_u8 crcbuf[2];
-       uae_u16 crcv;
-       int i;
-
-       if (pre)
-               bytes_mfm_add (fdi, 0, 12);
-       word_add (fdi, 0x4489); 
-       word_add (fdi, 0x4489); 
-       word_add (fdi, 0x4489); 
-       secbuf[0] = 0xfe;
-       if (secnum >= 0) {
-               secbuf[1] = (uae_u8)(fdi->current_track/2);
-               secbuf[2] = (uae_u8)(fdi->current_track%2);
-               secbuf[3] = (uae_u8)secnum;
-               secbuf[4] = 2;
-       } else {
-               memcpy (secbuf + 1, data, 4);
-       }
-       ibm_crc (secbuf[0], 1); 
-       ibm_crc (secbuf[1], 0); 
-       ibm_crc (secbuf[2], 0); 
-       ibm_crc (secbuf[3], 0); 
-       crcv = ibm_crc (secbuf[4], 0);
-       if (crc) {
-               memcpy (crcbuf, crc, 2);
-       } else {
-               crcbuf[0] = (uae_u8)(crcv >> 8);
-               crcbuf[1] = (uae_u8)crcv;
-       }
-       /* data */
-       for (i = 0;i < 5; i++)
-               byte_mfm_add (fdi, secbuf[i]);
-       /* crc */
-       byte_mfm_add (fdi, crcbuf[0]);
-       byte_mfm_add (fdi, crcbuf[1]);
-}
-
-/* standard IBM        index address mark */
-static void s10(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0, 12);
-       word_add (fdi, 0x5224); 
-       word_add (fdi, 0x5224); 
-       word_add (fdi, 0x5224); 
-       byte_mfm_add (fdi, 0xfc);
-}
-/* standard IBM        pre-gap */
-static void s11(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0x4e, 78);
-       bit_dedrop (fdi);
-       s10 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 50);
-}
-/* standard ST pre-gap */
-static void s12(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0x4e, 78);
-}
-/* standard extended IBM sector        header */
-static void s13(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s13:header=%s", datalog (fdi->track_src, 4));
-       ibm_sector_header (fdi, fdi->track_src, 0, -1, 1);
-       fdi->track_src += 4;
-}
-/* standard mini-extended IBM sector header */
-static void s14(FDI *fdi)
-{
-       debuglog ("s14:header=%s", datalog (fdi->track_src, 4));
-       ibm_sector_header (fdi, fdi->track_src, 0, -1, 0);
-       fdi->track_src += 4;
-}
-/* standard short IBM sector header */
-static void s15(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s15:sector=%d", *fdi->track_src);
-       ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1);
-}
-/* standard mini-short IBM sector header */
-static void s16(FDI *fdi)
-{
-       debuglog ("s16:track=%d", *fdi->track_src);
-       ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0);
-}
-/* standard CRC-incorrect mini-extended        IBM sector header */
-static void s17(FDI *fdi)
-{
-       debuglog ("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
-       ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0);
-       fdi->track_src += 4 + 2;
-}
-/* standard CRC-incorrect mini-short IBM sector        header */
-static void s18(FDI *fdi)
-{
-       debuglog ("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4)); 
-       ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0);
-       fdi->track_src += 1 + 4;
-}
-/* standard 512-byte CRC-correct IBM data */
-static void s19(FDI *fdi)
-{
-       debuglog ("s19:data=%s", datalog (fdi->track_src , 512));
-       ibm_data (fdi, fdi->track_src, 0, 512); 
-       fdi->track_src += 512;
-}
-/* standard 128*2^x-byte-byte CRC-correct IBM data */
-static void s1a(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog ("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
-       ibm_data (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift; 
-}
-/* standard 128*2^x-byte-byte CRC-incorrect IBM        data */ 
-static void s1b(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog ("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift)); 
-       ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift);
-       fdi->track_src += (128 << shift) + 2;
-}
-/* standard extended IBM sector        */
-static void s1c(FDI *fdi)
-{
-       int shift = fdi->track_src[3];
-       s13 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 22);
-       bytes_mfm_add (fdi, 0x00, 12);
-       ibm_data (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift; 
-}
-/* standard short IBM sector */        
-static void s1d(FDI *fdi)
-{
-       s15 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 22);
-       bytes_mfm_add (fdi, 0x00, 12);
-       s19 (fdi);
-}
-
-/* end marker */
-static void sff(FDI *fdi)
-{
-}
-
-typedef        void (*decode_described_track_func)(FDI*);
-
-static decode_described_track_func decode_sectors_described_track[] =
-{
-       s00,s01,s02,s03,s04,dxx,dxx,dxx,s08,s09,s0a,s0b,s0c,s0d,dxx,dxx, /* 00-0F */
-       s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s1a,s1b,s1c,s1d,dxx,dxx, /* 10-1F */
-       s20,s21,s22,s23,s24,s25,s26,s27,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 20-2F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 30-3F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 40-4F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 50-5F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 60-6F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 70-7F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 80-8F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 90-9F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* A0-AF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* B0-BF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* C0-CF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* D0-DF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* E0-EF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,sff  /* F0-FF */
-};
-
-static void track_amiga        (struct fdi *fdi, int first_sector, int max_sector)
-{
-       int i;
-
-       bit_add (fdi, 0);
-       bit_drop_next (fdi);
-       for (i = 0; i < max_sector; i++) {
-               amiga_sector_header (fdi, 0, 0, first_sector, max_sector - i);
-               amiga_data (fdi, fdi->track_src + first_sector * 512);
-               first_sector++; 
-               if (first_sector >= max_sector) first_sector = 0;
-       }
-       bytes_mfm_add (fdi, 0, 260); /* gap */
-}
-static void track_atari_st (struct fdi *fdi, int max_sector)
-{
-       int i, gap3;
-       uae_u8 *p = fdi->track_src;
-
-       switch (max_sector)
-               {
-               case 9: 
-               gap3 = 40;
-               break;
-               case 10:
-               gap3 = 24;
-               break;
-       }
-       s15 (fdi);
-       for (i = 0; i < max_sector; i++) {
-               byte_mfm_add (fdi, 0x4e);
-               byte_mfm_add (fdi, 0x4e);
-               ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
-               ibm_data (fdi, p + i * 512, 0, 512);
-               bytes_mfm_add (fdi, 0x4e, gap3);
-       }
-       bytes_mfm_add (fdi, 0x4e, 660 - gap3);
-       fdi->track_src += fdi->track_len * 256; 
-}
-static void track_pc (struct fdi *fdi, int max_sector)
-{
-       int i, gap3;
-       uae_u8 *p = fdi->track_src;
-
-       switch (max_sector)
-               {
-               case 8: 
-               gap3 = 116;
-               break;
-               case 9: 
-               gap3 = 54;
-               break;
-               default:
-               gap3 = 100; /* fixme */ 
-               break;
-       }
-       s11 (fdi);
-       for (i = 0; i < max_sector; i++) {
-               byte_mfm_add (fdi, 0x4e);
-               byte_mfm_add (fdi, 0x4e);
-               ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
-               ibm_data (fdi, p + i * 512, 0, 512);
-               bytes_mfm_add (fdi, 0x4e, gap3);
-       }
-       bytes_mfm_add (fdi, 0x4e, 600 - gap3);
-       fdi->track_src += fdi->track_len * 256; 
-}
-
-/* amiga dd */
-static void track_amiga_dd (struct fdi *fdi)
-{
-       uae_u8 *p = fdi->track_src;
-       track_amiga (fdi, fdi->track_len >> 4, 11);
-       fdi->track_src = p + (fdi->track_len & 15) * 512;
-}
-/* amiga hd */
-static void track_amiga_hd (struct fdi *fdi)
-{
-       uae_u8 *p = fdi->track_src;
-       track_amiga (fdi, 0, 22);
-       fdi->track_src = p + fdi->track_len * 256;
-}
-/* atari st 9 sector */        
-static void track_atari_st_9 (struct fdi *fdi)
-{
-       track_atari_st (fdi, 9);
-}
-/* atari st 10 sector */
-static void track_atari_st_10 (struct fdi *fdi)        
-{
-       track_atari_st (fdi, 10);
-}
-/* pc 8        sector */
-static void track_pc_8 (struct fdi *fdi)
-{
-       track_pc (fdi, 8);
-}
-/* pc 9        sector */
-static void track_pc_9 (struct fdi *fdi)
-{
-       track_pc (fdi, 9);
-}
-/* pc 15 sector        */
-static void track_pc_15        (struct fdi *fdi)
-{
-       track_pc (fdi, 15);
-}
-/* pc 18 sector        */
-static void track_pc_18        (struct fdi *fdi)
-{
-       track_pc (fdi, 18);
-}
-/* pc 36 sector        */
-static void track_pc_36        (struct fdi *fdi)
-{
-       track_pc (fdi, 36);
-}
-
-typedef        void (*decode_normal_track_func)(FDI*); 
-
-static decode_normal_track_func        decode_normal_track[] = 
-{ 
-       track_empty, /* 0 */
-       track_amiga_dd, track_amiga_hd, /* 1-2 */
-       track_atari_st_9, track_atari_st_10, /* 3-4 */
-       track_pc_8, track_pc_9, track_pc_15, track_pc_18, track_pc_36, /* 5-9 */
-       zxx,zxx,zxx,zxx,zxx /* A-F */
-};
-
-static void fix_mfm_sync (FDI *fdi)
-{
-       int i, pos, off1, off2, off3, mask1, mask2, mask3;
-
-       for (i = 0; i < fdi->mfmsync_offset; i++) {
-               pos = fdi->mfmsync_buffer[i];
-               off1 = (pos - 1) >> 3;
-               off2 = (pos + 1) >> 3;
-               off3 = pos >> 3;
-               mask1 = 1 << (7 - ((pos - 1) & 7));
-               mask2 = 1 << (7 - ((pos + 1) & 7));
-               mask3 = 1 << (7 - (pos & 7));
-               if (!(fdi->track_dst[off1] & mask1) && !(fdi->track_dst[off2] & mask2)) 
-                       fdi->track_dst[off3] |= mask3;
-               else
-                       fdi->track_dst[off3] &= ~mask3; 
-       }
-}
-
-static int handle_sectors_described_track (FDI *fdi)
-{
-       int oldout;
-       uae_u8 *start_src = fdi->track_src ;
-       fdi->encoding_type = *fdi->track_src++; 
-       fdi->index_offset = get_u32(fdi->track_src);
-       fdi->index_offset >>= 8;
-       fdi->track_src += 3;
-       outlog ("sectors_described, index offset: %d\n",fdi->index_offset);
-
-       do {
-               fdi->track_type = *fdi->track_src++;
-               outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
-               oldout = fdi->out;
-               decode_sectors_described_track[fdi->track_type](fdi);
-               outlog(" %d\n", fdi->out - oldout);
-               oldout = fdi->out;
-               if (fdi->out < 0 || fdi->err) { 
-                       outlog ("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
-                       return -1;
-               }
-               if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) {
-                       outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
-                       return -1;
-               }
-       } while (fdi->track_type != 0xff);
-       outlog("\n");
-       fix_mfm_sync (fdi);
-       return fdi->out;
-}
-
-static uae_u8 *fdi_decompress (int pulses, uae_u8 *sizep, uae_u8 *src, int *dofree)
-{
-       uae_u32 size = get_u24 (sizep); 
-       uae_u32 *dst2;
-       int len = size & 0x3fffff;
-       uae_u8 *dst;
-       int mode = size >> 22, i;
-
-       *dofree = 0;
-       if (mode == 0 && pulses * 2 > len)
-               mode = 1;
-       if (mode == 0) {
-               dst2 = (uae_u32*)src;
-               dst = src;
-               for (i = 0; i < pulses; i++) {
-                       *dst2++ = get_u32 (src);                        
-                       src += 4;
-               }
-       } else if (mode == 1) { 
-               dst = fdi_malloc (pulses *4);
-               *dofree = 1;
-               fdi_decode (src, pulses, dst);
-       } else {
-               dst = 0;
-       }
-       return dst;
-}
-
-static void dumpstream(int track, uae_u8 *stream, int len)
-{
-#if 0
-    char name[100];
-    FILE *f;
-
-    sprintf (name, "track_%d.raw", track);
-    f =        fopen(name, "wb");
-    fwrite (stream, 1, len * 4,        f);
-    fclose (f);        
-#endif
-}    
-
-static int bitoffset;
-
-STATIC_INLINE void addbit (uae_u8 *p, int bit)
-{
-       int off1 = bitoffset / 8;
-       int off2 = bitoffset % 8;
-       p[off1] |= bit << (7 - off2);
-       bitoffset++;
-}
-
-
-struct pulse_sample {
-       unsigned long size;
-       int number_of_bits;
-};
-
-#define        FDI_MAX_ARRAY 10 /* change this value as you want */
-static int pulse_limitval = 15; /* tolerance of 15% */
-static struct pulse_sample psarray[FDI_MAX_ARRAY];
-static int array_index;        
-static unsigned        long total;
-static int totaldiv;
-
-static void init_array(unsigned        long standard_MFM_2_bit_cell_size, int nb_of_bits)
-{
-       int i;
-       
-       for (i = 0; i < FDI_MAX_ARRAY; i++) {
-               psarray[i].size = standard_MFM_2_bit_cell_size; // That is (total track length / 50000) for Amiga double density
-               total += psarray[i].size;
-               psarray[i].number_of_bits = nb_of_bits; 
-               totaldiv += psarray[i].number_of_bits;
-       }
-       array_index = 0;
-}
-
-static void fdi2_mfm_decode(FDI        *fdi, unsigned long totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int pulses)
-{
-       unsigned long adjust;
-       unsigned long adjusted_pulse;
-       unsigned long standard_MFM_2_bit_cell_size = totalavg / 50000;
-       unsigned long standard_MFM_8_bit_cell_size = totalavg / 12500;
-       int real_size, i, j, nexti, eodat, outstep, randval;
-       uae_u8 *d = fdi->track_dst_buffer;
-       uae_u16 *pt = fdi->track_dst_buffer_timing;
-       uae_u32 ref_pulse, pulse;
-       long jitter;
-
-       /* detects a long-enough stable pulse coming just after another stable pulse */
-       i = 1;
-       while ( (i < pulses) && ( (idx[i] < maxidx)
-               || (idx[i - 1] < maxidx)
-               || (minp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
-                       i++;
-       if (i == pulses)  {
-               outlog ("No stable and long-enough pulse in track.\n");
-               return;
-       }
-       nexti = i;
-       eodat = i;
-       i--;
-       adjust = 0;
-       total = 0;
-       totaldiv = 0;
-       init_array(standard_MFM_2_bit_cell_size, 2);
-       bitoffset = 0;
-       ref_pulse = 0;
-       jitter = 0;
-       outstep = -1;
-       while (outstep < 2) {
-
-               /* calculates the current average bitrate from previous decoded data */
-               uae_u32 avg_size = (total << 3) / totaldiv; /* this is the new average size for one MFM bit */
-               /* uae_u32 avg_size = (uae_u32)((((float)total)*8.0) / ((float)totaldiv)); */
-               /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
-               if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) ||
-                       (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) {
-                               //init_array(standard_MFM_2_bit_cell_size, 2);
-                               avg_size = standard_MFM_8_bit_cell_size;
-               }
-               /* this is to prevent the average value from going too far
-               * from the theoretical value, otherwise it could progressively go to (2 *
-               * real value), or (real value / 2), etc. */
-
-               /* gets the next long-enough pulse (this may require more than one pulse) */
-               pulse = 0;
-               while (pulse < ((avg_size / 4) - (avg_size / 16))) {
-                       uae_u32 avg_pulse, min_pulse, max_pulse;
-                       i++;
-                       if (i >= pulses)
-                               i = 0;
-                       if (i == nexti) {
-                               do {
-                                       nexti++;
-                                       if (nexti >= pulses)
-                                               nexti = 0;
-                               } while (idx[nexti] < maxidx);
-                       }
-                       if (idx[i] >= maxidx) { /* stable pulse */
-                               avg_pulse = avgp[i] - jitter;
-                               min_pulse = minp[i];
-                               max_pulse = maxp[i];
-                               if (jitter >= 0)
-                                       min_pulse -= jitter;
-                               else
-                                       max_pulse -= jitter;
-                               if ((maxp[nexti] - avgp[nexti]) < (avg_pulse - min_pulse))
-                                       min_pulse = avg_pulse - (maxp[nexti] - avgp[nexti]);
-                               if ((avgp[nexti] - minp[nexti]) < (max_pulse - avg_pulse))
-                                       max_pulse = avg_pulse + (avgp[nexti] - minp[nexti]);
-                               if (min_pulse < ref_pulse)
-                                       min_pulse = ref_pulse;
-                               randval = rand();
-                               if (randval < (RAND_MAX / 2)) {
-                                       if (randval > (RAND_MAX / 4)) {
-                                               if (randval <= (3 * RAND_MAX / 8))
-                                                       randval = (2 * randval) - (RAND_MAX /4);
-                                               else
-                                                       randval = (4 * randval) - RAND_MAX;
-                                       }
-                                       jitter = 0 - (randval * (avg_pulse - min_pulse)) / RAND_MAX;
-                               } else {
-                                       randval -= RAND_MAX / 2;
-                                       if (randval > (RAND_MAX / 4)) {
-                                               if (randval <= (3 * RAND_MAX / 8))
-                                                       randval = (2 * randval) - (RAND_MAX /4);
-                                               else
-                                                       randval = (4 * randval) - RAND_MAX;
-                                       }
-                                       jitter = (randval * (max_pulse - avg_pulse)) / RAND_MAX;
-                               }
-                               avg_pulse += jitter;
-                               if ((avg_pulse < min_pulse) || (avg_pulse > max_pulse)) {
-                                       outlog ("avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse);
-                                       outlog("avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n",
-                                               avgp[i], avgp[nexti], minp[i], minp[nexti], maxp[i], maxp[nexti], jitter, i, nexti);
-                               }
-                               if (avg_pulse < ref_pulse)
-                                       outlog ("avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse);
-                               pulse += avg_pulse - ref_pulse;
-                               ref_pulse = 0;
-                               if (i == eodat)
-                                       outstep++;
-                       } else if (rand() <= ((idx[i] * RAND_MAX) / maxidx)) {
-                               avg_pulse = avgp[i];
-                               min_pulse = minp[i];
-                               max_pulse = maxp[i];
-                               randval = rand();
-                               if (randval < (RAND_MAX / 2)) {
-                                       if (randval > (RAND_MAX / 4)) {
-                                               if (randval <= (3 * RAND_MAX / 8))
-                                                       randval = (2 * randval) - (RAND_MAX /4);
-                                               else
-                                                       randval = (4 * randval) - RAND_MAX;
-                                       }
-                                       avg_pulse -= (randval * (avg_pulse - min_pulse)) / RAND_MAX;
-                               } else {
-                                       randval -= RAND_MAX / 2;
-                                       if (randval > (RAND_MAX / 4)) {
-                                               if (randval <= (3 * RAND_MAX / 8))
-                                                       randval = (2 * randval) - (RAND_MAX /4);
-                                               else
-                                                       randval = (4 * randval) - RAND_MAX;
-                                       }
-                                       avg_pulse += (randval * (max_pulse - avg_pulse)) / RAND_MAX;
-                               }
-                               if ((avg_pulse > ref_pulse) && (avg_pulse < (avgp[nexti] - jitter))) {
-                                       pulse += avg_pulse - ref_pulse;
-                                       ref_pulse = avg_pulse;
-                               }
-                       }
-               }
-
-               /* gets the size in bits from the pulse width, considering the current average bitrate */
-               adjusted_pulse = pulse;
-               real_size = 0;
-               while (adjusted_pulse >= avg_size) {
-                       real_size += 4;
-                       adjusted_pulse -= avg_size / 2;
-               }
-               adjusted_pulse <<= 3;
-               while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) {
-                       real_size += 2;
-                       adjusted_pulse -= avg_size * 2;
-               }
-               if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) {
-                       if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) {
-                               if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4)))
-                                       real_size += 3;
-                               else
-                                       real_size += 4;
-                       } else
-                               real_size += 4;
-               } else {
-                       if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) {
-                               real_size += 3;
-                       } else {
-                               if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) {
-                                       if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4)))
-                                               real_size += 2;
-                                       else
-                                               real_size += 3;
-                               } else
-                                       real_size += 2;
-                       }
-               }
-
-               if (outstep == 1) {
-                       for (j = real_size; j > 1; j--)
-                               addbit (d, 0);
-                       addbit (d, 1);
-                       for (j = 0; j < real_size; j++) 
-                               *pt++ = (uae_u16)(pulse / real_size);
-               }
-               
-               /* prepares for the next pulse */
-               adjust = ((real_size * avg_size)/8) - pulse;
-               total -= psarray[array_index].size;
-               totaldiv -= psarray[array_index].number_of_bits;
-               psarray[array_index].size = pulse;
-               psarray[array_index].number_of_bits = real_size;
-               total += pulse; 
-               totaldiv += real_size;
-               array_index++;
-               if (array_index >= FDI_MAX_ARRAY)
-                       array_index = 0;
-       }
-
-       fdi->out = bitoffset;
-}
-
-static void fdi2_celltiming (FDI *fdi, unsigned        long totalavg, int bitoffset, uae_u16 *out)
-{
-       uae_u16 *pt2, *pt;
-       double avg_bit_len;
-       int i;
-
-       avg_bit_len = (double)totalavg / (double)bitoffset;
-       pt2 = fdi->track_dst_buffer_timing;
-       pt = out;
-       for (i = 0; i < bitoffset / 8; i++) {
-               double v = (pt2[0] + pt2[1] + pt2[2] + pt2[3] + pt2[4] + pt2[5] + pt2[6] + pt2[7]) / 8.0;
-               v = 1000.0 * v / avg_bit_len;
-               *pt++ = (uae_u16)v;
-               pt2 += 8;
-       }
-       *out++ = *pt;
-       *out = *pt;
-}
-
-static int decode_lowlevel_track (FDI *fdi, int        *indexoffsetp, int track, struct fdi_cache *cache)
-{
-       uae_u8 *p1, *d; 
-       uae_u32 *p2;
-       uae_u32 *avgp, *minp = 0, *maxp = 0;
-       uae_u8 *idxp = 0;
-       uae_u32 maxidx, minidx, totalavg, weakbits;
-       int i, len, pulses, indexoffset;
-       int avg_free, min_free = 0, max_free = 0, idx_free;
-       int idx_off1, idx_off2, idx_off3;
-
-       d = fdi->track_dst;
-       p1 = fdi->track_src;
-       pulses = get_u32 (p1);
-       if (!pulses)
-               return -1;
-       p1 += 4;
-       len = 12;
-       avgp = (uae_u32*)fdi_decompress (pulses, p1 + 0, p1 + len, &avg_free);
-       dumpstream(track, (uae_u8*)avgp, pulses);
-       len += get_u24 (p1 + 0) & 0x3fffff;
-       if (!avgp)
-               return -1;
-       if (get_u24 (p1 + 3) && get_u24 (p1 + 6)) {
-               minp = (uae_u32*)fdi_decompress (pulses, p1 + 3, p1 + len, &min_free);
-               len += get_u24 (p1 + 3) & 0x3fffff;
-               maxp = (uae_u32*)fdi_decompress (pulses, p1 + 6, p1 + len, &max_free);
-               len += get_u24 (p1 + 6) & 0x3fffff;
-               /* Computes the real min and max values */
-               for (i = 0; i < pulses; i++) {
-                       maxp[i] = avgp[i] + minp[i] - maxp[i];
-                       minp[i] = avgp[i] - minp[i];
-               }
-       } else {
-               minp = avgp;
-               maxp = avgp;
-       }
-       if (get_u24 (p1 + 9)) { 
-               idx_off1 = 0;
-               idx_off2 = 1;
-               idx_off3 = 2;
-               idxp = fdi_decompress (pulses, p1 + 9, p1 + len, &idx_free);
-               if (idx_free) { 
-                       if (idxp[0] == 0 && idxp[1] == 0) {
-                               idx_off1 = 2;
-                               idx_off2 = 3;
-                       } else {
-                               idx_off1 = 1;
-                               idx_off2 = 0;
-                       }
-                       idx_off3 = 4;
-               }
-       } else {
-               idxp = fdi_malloc (pulses * 2); 
-               idx_free = 1;
-               for (i = 0; i < pulses; i++) {
-                       idxp[i * 2 + 0] = 2;
-                       idxp[i * 2 + 1] = 0;
-               }
-               idxp[0] = 1;
-               idxp[1] = 1;
-       }
-
-       maxidx = 0;
-       minidx = 255;
-       indexoffset = 0;
-       p1 = idxp;
-       for (i = 0; i < pulses; i++) {
-               if (p1[idx_off1] + p1[idx_off2] > maxidx)
-                       maxidx = p1[idx_off1] + p1[idx_off2];
-               if (abs (p1[idx_off1] - p1[idx_off2]) < minidx) {
-                       minidx = abs (p1[idx_off1] - p1[idx_off2]);
-                       indexoffset = i;
-               }
-               p1 += idx_off3; 
-       }
-       p1 = idxp;
-       p2 = avgp;
-       totalavg = 0;
-       weakbits = 0;
-       for (i = 0; i < pulses; i++) {
-               int sum = p1[idx_off1] + p1[idx_off2];
-               if (sum >= maxidx) {
-                       totalavg += *p2;
-               } else {
-                       weakbits++;
-               }
-               p2++;
-               p1 += idx_off3; 
-               idxp[i] = sum;
-       }
-       len = totalavg / 100000;
-       outlog("totalavg=%u index=%d maxidx=%d weakbits=%d len=%d\n",
-               totalavg, indexoffset, maxidx, weakbits, len);
-       cache->avgp = avgp;
-       cache->idxp = idxp;
-       cache->minp = minp;
-       cache->maxp = maxp;
-       cache->avg_free = avg_free;
-       cache->idx_free = idx_free;
-       cache->min_free = min_free;
-       cache->max_free = max_free;
-       cache->totalavg = totalavg;
-       cache->pulses = pulses;
-       cache->maxidx = maxidx;
-       cache->indexoffset = indexoffset;
-       cache->weakbits = weakbits;
-       cache->lowlevel = 1;
-
-       return 1;
-}
-
-static unsigned        char fdiid[]={"Formatted Disk Image file"};
-static int bit_rate_table[16] =        { 125,150,250,300,500,1000 };
-
-void fdi2raw_header_free (FDI *fdi)
-{
-       int i;
-
-       fdi_free (fdi->mfmsync_buffer); 
-       fdi_free (fdi->track_src_buffer);
-       fdi_free (fdi->track_dst_buffer);
-       fdi_free (fdi->track_dst_buffer_timing);
-       for (i = 0; i < MAX_TRACKS; i++) {
-               struct fdi_cache *c = &fdi->cache[i];
-               if (c->idx_free)
-                       fdi_free (c->idxp);
-               if (c->avg_free)
-                       fdi_free (c->avgp);
-               if (c->min_free)
-                       fdi_free (c->minp);
-               if (c->max_free)
-                       fdi_free (c->maxp);
-       }
-       fdi_free (fdi); 
-       debuglog ("FREE: memory allocated %d\n", fdi_allocated);
-}
-
-int fdi2raw_get_last_track (FDI        *fdi)
-{
-       return fdi->last_track; 
-}
-
-int fdi2raw_get_num_sector (FDI        *fdi)
-{
-       if (fdi->header[152] == 0x02)
-               return 22;
-       return 11;
-}
-
-int fdi2raw_get_last_head (FDI *fdi)
-{
-       return fdi->last_head;
-}
-
-int fdi2raw_get_rotation (FDI *fdi)
-{
-       return fdi->rotation_speed;
-}
-
-int fdi2raw_get_bit_rate (FDI *fdi)
-{
-       return fdi->bit_rate;
-}
-
-int fdi2raw_get_type (FDI *fdi)        
-{
-       return fdi->disk_type;
-}
-
-int fdi2raw_get_write_protect (FDI *fdi)
-{
-       return fdi->write_protect;
-}
-
-FDI *fdi2raw_header(struct zfile *f)
-{
-       int i, offset, oldseek; 
-       uae_u8 type, size;
-       FDI *fdi;
-
-       debuglog ("ALLOC: memory allocated %d\n", fdi_allocated);
-       fdi = fdi_malloc(sizeof(FDI));
-       memset (fdi, 0, sizeof (FDI));
-       fdi->file = f;
-       oldseek = zfile_ftell (fdi->file);
-       zfile_fseek (fdi->file, 0, SEEK_SET);
-       zfile_fread (fdi->header, 2048, 1, fdi->file);
-       zfile_fseek (fdi->file, oldseek, SEEK_SET);
-       if (memcmp (fdiid, fdi->header, strlen (fdiid)) ) {
-               fdi_free(fdi);
-               return NULL;
-       }
-       if ((fdi->header[140] != 1 && fdi->header[140] != 2) || fdi->header[141] != 0) {
-               fdi_free(fdi);
-               return NULL;
-       }
-
-       fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
-       fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER);
-       fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER);
-       fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER);
-       
-       fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1;
-       fdi->last_track *= fdi->header[144] + 1;
-       if (fdi->last_track > MAX_TRACKS)
-               fdi->last_track = MAX_TRACKS;
-       fdi->last_head = fdi->header[144];
-       fdi->disk_type = fdi->header[145];
-       fdi->rotation_speed = fdi->header[146] + 128;
-       fdi->write_protect = fdi->header[147] & 1;
-       outlog ("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
-       outlog ("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed);
-
-       offset = 512;
-       i = fdi->last_track;
-       if (i > 180) {
-               offset += 512;
-               i -= 180;
-               while (i > 256) {
-                       offset += 512;
-                       i -= 256;
-               }
-       }
-       for (i = 0; i < fdi->last_track; i++) { 
-               fdi->track_offsets[i] = offset; 
-               type = fdi->header[152 + i * 2];
-               size = fdi->header[152 + i * 2 + 1];
-               if (type == 1)
-                       offset += (size & 15) * 512;
-               else if ((type & 0xc0) == 0x80) 
-                       offset += (((type & 0x3f) << 8) | size) * 256;
-               else
-                       offset += size * 256;
-       }
-       fdi->track_offsets[i] = offset; 
-
-       return fdi;
-}
-
-
-int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev)
-{
-       struct fdi_cache *cache = &fdi->cache[track];
-       int len, i;
-
-       memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
-       fdi2_mfm_decode (fdi, cache->totalavg,
-               cache->avgp, cache->minp, cache->maxp, cache->idxp,
-               cache->maxidx, cache->pulses);
-       //fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses);
-       outlog("track %d: number of bits=%d avg len=%.2f weakbits=%d\n",
-           track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits);
-       len = fdi->out;
-       if (cache->weakbits >= 10 && multirev)
-               *multirev = 1;
-       *tracklength = len;
-
-       for (i = 0; i < (len + 15) / (2 * 8); i++) {
-               uae_u8 *data = fdi->track_dst_buffer + i * 2;
-               *mfmbuf++ = 256 * *data + *(data + 1);
-       }               
-       fdi2_celltiming (fdi, cache->totalavg, len, tracktiming);
-       if (indexoffsetp)
-               *indexoffsetp = cache->indexoffset;
-       return 1;
-}
-
-int fdi2raw_loadrevolution (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength)
-{
-       return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, 0, 0);
-}
-
-int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev)
-{
-       uae_u8 *p;
-       int outlen, i, indexoffset = 0;
-       struct fdi_cache *cache = &fdi->cache[track];
-
-       if (cache->lowlevel)
-               return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev);
-
-       fdi->err = 0;
-       fdi->track_src_len = fdi->track_offsets[track + 1] - fdi->track_offsets[track]; 
-       zfile_fseek (fdi->file, fdi->track_offsets[track], SEEK_SET);
-       zfile_fread (fdi->track_src_buffer, fdi->track_src_len, 1, fdi->file);
-       memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
-       fdi->track_dst_buffer_timing[0] = 0;
-
-       fdi->current_track = track;
-       fdi->track_src = fdi->track_src_buffer; 
-       fdi->track_dst = fdi->track_dst_buffer; 
-       p = fdi->header + 152 + fdi->current_track * 2; 
-       fdi->track_type = *p++; 
-       fdi->track_len = *p++;
-       fdi->bit_rate = 0;
-       fdi->out = 0;
-       fdi->mfmsync_offset = 0;
-
-       if ((fdi->track_type & 0xf0) == 0xf0 || (fdi->track_type & 0xf0) == 0xe0)
-               fdi->bit_rate = bit_rate_table[fdi->track_type & 0x0f]; 
-       else
-               fdi->bit_rate = 250;
-
-       outlog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
-               fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate);
-
-       if ((fdi->track_type & 0xc0) == 0x80) { 
-
-               outlen = decode_lowlevel_track (fdi, &indexoffset, track, cache);
-
-       } else if ((fdi->track_type & 0xf0) == 0xf0) {
-
-               outlen = decode_raw_track (fdi);
-
-       } else if ((fdi->track_type & 0xf0) == 0xe0) {
-
-               outlen = handle_sectors_described_track (fdi);
-
-       } else if ((fdi->track_type & 0xf0)) {
-
-               zxx (fdi);
-               outlen = -1;
-               
-       } else if (fdi->track_type < 0x10) {
-
-               decode_normal_track[fdi->track_type](fdi);
-               fix_mfm_sync (fdi);
-               outlen = fdi->out;
-
-       } else {
-
-               zxx (fdi);
-               outlen = -1;
-
-       }
-
-//     amiga_check_track (fdi);
-
-       if (fdi->err)
-               return 0;
-
-       if (outlen > 0) {
-               if (cache->lowlevel)
-                       return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev);
-               *tracklength = fdi->out;
-               for (i = 0; i < ((*tracklength) + 15) / (2 * 8); i++) {
-                       uae_u8 *data = fdi->track_dst_buffer + i * 2;
-                       *mfmbuf++ = 256 * *data + *(data + 1);
-               }
-       }
-       return outlen;
-}
-
diff --git a/fdi2raw_old.c b/fdi2raw_old.c
deleted file mode 100755 (executable)
index 42efc71..0000000
+++ /dev/null
@@ -1,1835 +0,0 @@
-/*
-
-  FDI to raw bit stream converter
-  Copyright (c) 2001 by Toni Wilen <twilen@arabuusimiehet.com>
-  FDI 2.0 support
-  Copyright (c) 2003-2004 by Toni Wilen <twilen@arabuusimiehet.com>
-                    and Vincent Joguin
-
-  FDI format created by Vincent "ApH" Joguin
-
-  Tiny changes - function type fixes, multiple drives, addition of
-  get_last_head and C++ callability - by Thomas Harte, 2001,
-  T.Harte@excite.co.uk
-
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along
-  with this program; if not, write to the Free Software Foundation, Inc.,
-  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* IF UAE */
-#include "sysconfig.h"
-#include "sysdeps.h"
-#include "zfile.h"
-/* ELSE */
-//#include "types.h"
-
-#include "fdi2raw.h"
-
-#undef DEBUG
-#define VERBOSE
-
-#include <assert.h>
-
-#ifdef DEBUG
-static char *datalog(uae_u8 *src, int len)
-{
-       static char buf[1000];
-       static int offset;
-       int i = 0, offset2;
-
-       offset2 = offset;
-       buf[offset++]='\'';
-       while(len--) {
-               sprintf (buf + offset, "%02.2X", src[i]);
-               offset += 2;
-               i++;
-               if (i > 10) break;
-       }
-       buf[offset++]='\'';
-       buf[offset++] = 0;
-       if (offset >= 900) offset = 0;
-       return buf + offset2;
-}
-#else
-static char *datalog(uae_u8 *src, int len) { return ""; }
-#endif
-
-#ifdef DEBUG
-#define debuglog write_log
-#else
-#define debuglog
-#endif
-#ifdef VERBOSE
-#define outlog write_log
-#else
-#define outlog
-#endif
-
-static int fdi_allocated;
-#ifdef DEBUG
-static void fdi_free (void *p)
-{
-       int size;
-       if (!p)
-               return;
-       size = ((int*)p)[-1];
-       fdi_allocated -= size;
-       write_log ("%d freed (%d)\n", size, fdi_allocated);
-       free ((int*)p - 1);
-}
-static void *fdi_malloc (int size)
-{
-       void *p = xmalloc (size + sizeof (int));
-       ((int*)p)[0] = size;
-       fdi_allocated += size;
-       write_log ("%d allocated (%d)\n", size, fdi_allocated);
-       return (int*)p + 1;
-}
-#else
-#define fdi_free free
-#define fdi_malloc xmalloc
-#endif
-
-#define MAX_SRC_BUFFER 4194304
-#define MAX_DST_BUFFER 40000
-#define MAX_MFM_SYNC_BUFFER 60000
-#define MAX_TIMING_BUFFER 400000
-#define MAX_TRACKS 166
-#define MAX_REVOLUTIONS 4
-
-struct fdi_cache {
-       uae_u8 *cache_buffer[MAX_REVOLUTIONS];
-       uae_u8 *cache_buffer_timing;
-       int length[MAX_REVOLUTIONS];
-       int indexoffset;
-};
-
-struct fdi {
-       uae_u8 *track_src_buffer;
-       uae_u8 *track_src;
-       int track_src_len;
-       uae_u8 *track_dst_buffer;
-       uae_u8 *track_dst;
-       uae_u16 *track_dst_buffer_timing;
-       uae_u8 track_len;
-       uae_u8 track_type;
-       int current_track;
-       int last_track;
-       int last_head;
-       int rotation_speed;
-       int bit_rate;
-       int disk_type;
-       int write_protect;
-       int err;
-       uae_u8 header[2048];
-       int track_offsets[MAX_TRACKS];
-       struct zfile *file;
-       int out;
-       int mfmsync_offset;
-       int *mfmsync_buffer;
-       /* sector described only */
-       int index_offset;
-       int encoding_type;
-       /* bit handling */
-       int nextdrop;
-       struct fdi_cache cache[MAX_TRACKS];
-};
-
-#define get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3]))
-#define get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2]))
-STATIC_INLINE put_u32 (uae_u8 *d, uae_u32 v)
-{
-       d[0] = v >> 24;
-       d[1] = v >> 16;
-       d[2] = v >> 8;
-       d[3] = v;
-}
-
-struct node {
-       uae_u16 v;
-       struct node *left;
-       struct node *right;
-};
-typedef struct node NODE;
-
-static uae_u8 temp, temp2;
-
-static uae_u8 *expand_tree (uae_u8 *stream, NODE *node)
-{
-       if (temp & temp2) {
-               fdi_free (node->left);
-               node->left = 0;
-               fdi_free (node->right);
-               node->right = 0;
-               temp2 >>= 1;
-               if (!temp2) {
-                       temp = *stream++;
-                       temp2 = 0x80;
-               }
-               return stream;
-       } else {
-               uae_u8 *stream_temp;
-               temp2 >>= 1;
-               if (!temp2) {
-                       temp = *stream++;
-                       temp2 = 0x80;
-               }
-               node->left = fdi_malloc (sizeof (NODE));
-               memset (node->left, 0, sizeof (NODE));
-               stream_temp = expand_tree (stream, node->left);
-               node->right = fdi_malloc (sizeof (NODE));
-               memset (node->right, 0, sizeof (NODE));
-               return expand_tree (stream_temp, node->right);
-       }
-}
-
-static uae_u8 *values_tree8 (uae_u8 *stream, NODE *node)
-{
-       if (node->left == 0) {
-               node->v = *stream++;
-               return stream;
-       } else {
-               uae_u8 *stream_temp = values_tree8 (stream, node->left);
-               return values_tree8 (stream_temp, node->right);
-       }
-}
-
-static uae_u8 *values_tree16 (uae_u8 *stream, NODE *node)
-{
-       if (node->left == 0) {
-               uae_u16 high_8_bits = (*stream++) << 8;
-               node->v = high_8_bits | (*stream++);
-               return stream;
-       } else {
-               uae_u8 *stream_temp = values_tree16 (stream, node->left);
-               return values_tree16 (stream_temp, node->right);
-       }
-}
-
-static void free_nodes (NODE *node)
-{
-       if (node) {
-               free_nodes (node->left);
-               free_nodes (node->right);
-               fdi_free (node);
-       }
-}
-
-static uae_u32 sign_extend16 (uae_u32 v)
-{
-       if (v & 0x8000)
-               v |= 0xffff0000;
-       return v;
-}
-
-static uae_u32 sign_extend8 (uae_u32 v)
-{
-       if (v & 0x80)
-               v |= 0xffffff00;
-       return v;
-}
-
-static void fdi_decode (uae_u8 *stream, int size, uae_u8 *out)
-{
-       int i;
-       uae_u8 sign_extend, sixteen_bit, sub_stream_shift;
-       NODE root;
-       NODE *current_node;
-
-       memset (out, 0, size * 4);
-       sub_stream_shift = 1;
-       while (sub_stream_shift) {
-
-               //sub-stream header decode
-               sign_extend = *stream++;
-               sub_stream_shift = sign_extend & 0x7f;
-               sign_extend &= 0x80;
-               sixteen_bit = (*stream++) & 0x80;
-
-               //huffman tree architecture decode
-               temp = *stream++;
-               temp2 = 0x80;
-               stream = expand_tree (stream, &root);
-               if (temp2 == 0x80)
-                       stream--;
-
-               //huffman output values decode
-               if (sixteen_bit)
-                       stream = values_tree16 (stream, &root);
-               else
-                       stream = values_tree8 (stream, &root);
-
-               //sub-stream data decode
-               temp2 = 0;
-               for (i = 0; i < size; i++) {
-                       uae_u32 v;
-                       uae_u8 decode = 1;
-                       current_node = &root;
-                       while (decode) {
-                               if (current_node->left == 0) {
-                                       decode = 0;
-                               } else {
-                                       temp2 >>= 1;
-                                       if (!temp2) {
-                                               temp2 = 0x80;
-                                               temp = *stream++;
-                                       }
-                                       if (temp & temp2)
-                                               current_node = current_node->right;
-                                       else
-                                               current_node = current_node->left;
-                               }
-                       }
-                       v = ((uae_u32*)out)[i];
-                       if (sign_extend) {
-                               if (sixteen_bit)
-                                       v |= sign_extend16 (current_node->v) << sub_stream_shift;
-                               else
-                                       v |= sign_extend8 (current_node->v) << sub_stream_shift;
-                       } else {
-                               v |= current_node->v << sub_stream_shift;
-                       }
-                       ((uae_u32*)out)[i] = v;
-               }
-               free_nodes (root.left);
-               free_nodes (root.right);
-       }
-}
-
-
-static int decode_raw_track (FDI *fdi)
-{
-       int size = get_u32(fdi->track_src);
-       memcpy (fdi->track_dst, fdi->track_src, (size + 7) >> 3);
-       fdi->track_src += (size + 7) >> 3;
-       return size;
-}
-
-/* unknown track */
-static void zxx (FDI *fdi)
-{
-       outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-//     return -1;
-}
-/* unsupported track */
-static void zyy (FDI *fdi)
-{
-       outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-//     return -1;
-}
-/* empty track */
-static void track_empty (FDI *fdi)
-{
-//     return 0;
-}
-
-/* unknown sector described type */
-static void dxx (FDI *fdi)
-{
-       outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
-       fdi->err = 1;
-}
-/* unsupported sector described type */
-static void dyy (FDI *fdi)
-{
-       outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type);
-       fdi->err = 1;
-}
-/* add position of mfm sync bit */
-static void add_mfm_sync_bit (FDI *fdi)
-{
-       if (fdi->nextdrop) {
-               fdi->nextdrop = 0;
-               return;
-       }
-       fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out;
-       if (fdi->out == 0) {
-               outlog ("illegal position for mfm sync bit, offset=%d\n",fdi->out);
-               fdi->err = 1;
-       }
-       if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) {
-               fdi->mfmsync_offset = 0;
-               outlog ("mfmsync buffer overflow\n");
-               fdi->err = 1;
-       }
-       fdi->out++;
-}
-
-#define BIT_BYTEOFFSET ((fdi->out) >> 3)
-#define BIT_BITOFFSET (7-((fdi->out)&7))
-
-/* add one bit */
-static void bit_add (FDI *fdi, int bit)
-{
-       if (fdi->nextdrop) {
-               fdi->nextdrop = 0;
-               return;
-       }
-       fdi->track_dst[BIT_BYTEOFFSET] &= ~(1 << BIT_BITOFFSET);
-       if (bit) 
-               fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET);
-       fdi->out++;
-       if (fdi->out >= MAX_DST_BUFFER * 8) {
-               outlog ("destination buffer overflow\n");
-               fdi->err = 1;
-               fdi->out = 1;
-       }
-}
-/* add bit and mfm sync bit */
-static void bit_mfm_add (FDI *fdi, int bit)
-{
-       add_mfm_sync_bit (fdi);
-       bit_add (fdi, bit);
-}
-/* remove following bit */
-static void bit_drop_next (FDI *fdi)
-{
-       if (fdi->nextdrop > 0) {
-               outlog("multiple bit_drop_next() called");
-       } else if (fdi->nextdrop < 0) {
-               fdi->nextdrop = 0;
-               debuglog(":DNN:");
-               return;
-       }
-       debuglog(":DN:");
-       fdi->nextdrop = 1;
-}
-
-/* ignore next bit_drop_next() */
-static void bit_dedrop (FDI *fdi)
-{
-       if (fdi->nextdrop) {
-               outlog("bit_drop_next called before bit_dedrop");
-       }
-       fdi->nextdrop = -1;
-       debuglog(":BDD:");
-}
-
-/* add one byte */
-static void byte_add (FDI *fdi, uae_u8 v)
-{
-       int i;
-       for (i = 7; i >= 0; i--)
-               bit_add (fdi, v & (1 << i));
-}
-/* add one word */
-static void word_add (FDI *fdi, uae_u16 v)
-{
-       byte_add (fdi, (uae_u8)(v >> 8));
-       byte_add (fdi, (uae_u8)v);
-}
-/* add one byte and mfm encode it */
-static void byte_mfm_add (FDI *fdi, uae_u8 v)
-{
-       int i;
-       for (i = 7; i >= 0; i--)
-               bit_mfm_add (fdi, v & (1 << i));
-}
-/* add multiple bytes and mfm encode them */
-static void bytes_mfm_add (FDI *fdi, uae_u8 v, int len)
-{
-       int i;
-       for (i = 0; i < len; i++) byte_mfm_add (fdi, v);
-}
-/* add one mfm encoded word and re-mfm encode it */
-static void word_post_mfm_add (FDI *fdi, uae_u16 v)
-{
-       int i;
-       for (i = 14; i >= 0; i -= 2)
-               bit_mfm_add (fdi, v & (1 << i));
-}
-
-/* bit 0 */
-static void s00(FDI *fdi) { bit_add (fdi, 0); }
-/* bit 1*/
-static void s01(FDI *fdi) { bit_add (fdi, 1); }
-/* 4489 */
-static void s02(FDI *fdi) { word_add (fdi, 0x4489); }
-/* 5224 */
-static void s03(FDI *fdi) { word_add (fdi, 0x5224); }
-/* mfm sync bit */
-static void s04(FDI *fdi) { add_mfm_sync_bit (fdi); }
-/* RLE MFM-encoded data */
-static void s08(FDI *fdi)
-{
-       int bytes = *fdi->track_src++;
-       uae_u8 byte = *fdi->track_src++;
-       if (bytes == 0) bytes = 256;
-       debuglog ("s08:len=%d,data=%02.2X",bytes,byte);
-       while(bytes--) byte_add (fdi, byte);
-}
-/* RLE MFM-decoded data */
-static void s09(FDI *fdi)
-{
-       int bytes = *fdi->track_src++;
-       uae_u8 byte = *fdi->track_src++;
-       if (bytes == 0) bytes = 256;
-       bit_drop_next (fdi);
-       debuglog ("s09:len=%d,data=%02.2X",bytes,byte);
-       while(bytes--) byte_mfm_add (fdi, byte);
-}
-/* MFM-encoded data */
-static void s0a(FDI *fdi)
-{
-       int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
-       uae_u8 b;
-       fdi->track_src += 2;
-       debuglog ("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) {
-               i = 7;
-               b = *fdi->track_src++;
-               while (bits--) {
-                       bit_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-encoded data */
-static void s0b(FDI *fdi)
-{
-       int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
-       uae_u8 b;
-       fdi->track_src += 2;
-       debuglog ("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) {
-               i = 7;
-               b = *fdi->track_src++;
-               while (bits--) {
-                       bit_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-decoded data */
-static void s0c(FDI *fdi)
-{
-       int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
-       uae_u8 b;
-       fdi->track_src += 2;
-       bit_drop_next (fdi);
-       debuglog ("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_mfm_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) {
-               i = 7;
-               b = *fdi->track_src++;
-               while(bits--) {
-                       bit_mfm_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-/* MFM-decoded data */
-static void s0d(FDI *fdi)
-{
-       int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
-       uae_u8 b;
-       fdi->track_src += 2;
-       bit_drop_next (fdi);
-       debuglog ("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
-       while (bits >= 8) {
-               byte_mfm_add (fdi, *fdi->track_src++);
-               bits -= 8;
-       }
-       if (bits > 0) {
-               i = 7;
-               b = *fdi->track_src++;
-               while(bits--) {
-                       bit_mfm_add (fdi, b & (1 << i));
-                       i--;
-               }
-       }
-}
-
-/* ***** */
-/* AMIGA */
-/* ***** */
-
-/* just for testing integrity of Amiga sectors */
-
-static void rotateonebit (uae_u8 *start, uae_u8 *end, int shift)
-{
-       if (shift == 0)
-               return;
-       while (start <= end) {
-               start[0] <<= shift;
-               start[0] |= start[1] >> (8 - shift);
-               start++;
-       }
-}
-
-static int check_offset;
-static uae_u16 getmfmword (uae_u8 *mbuf)
-{
-       uae_u32 v;
-
-       v = (mbuf[0] << 8) | (mbuf[1] << 0);
-       if (check_offset == 0)
-               return v;
-       v <<= 8;
-       v |= mbuf[2];
-       v >>= check_offset;
-       return v;
-}
-
-#define MFMMASK 0x55555555
-static uae_u32 getmfmlong (uae_u8 * mbuf)
-{
-       return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK;
-}
-
-static int amiga_check_track (FDI *fdi)
-{
-       int i, j, secwritten = 0;
-       int fwlen = fdi->out / 8;
-       int length = 2 * fwlen;
-       int drvsec = 11;
-       uae_u32 odd, even, chksum, id, dlong;
-       uae_u8 *secdata;
-       uae_u8 secbuf[544];
-       uae_u8 bigmfmbuf[60000];
-       uae_u8 *mbuf, *mbuf2, *mend;
-       char sectable[22];
-       uae_u8 *raw = fdi->track_dst_buffer;
-       int slabel, off;
-       int ok = 1;
-
-       memset (bigmfmbuf, 0, sizeof (bigmfmbuf));
-       mbuf = bigmfmbuf;
-       check_offset = 0;
-       for (i = 0; i < (fdi->out + 7) / 8; i++)
-               *mbuf++ = raw[i];
-       off = fdi->out & 7;
-#if 1
-       if (off > 0) {
-               mbuf--;
-               *mbuf &= ~((1 << (8 - off)) - 1);
-       }
-       j = 0;
-       while (i < (fdi->out + 7) / 8 + 600) {
-               *mbuf++ |= (raw[j] >> off) | ((raw[j + 1]) << (8 - off));
-               j++;
-               i++;
-       }
-#endif
-       mbuf = bigmfmbuf;
-
-       memset (sectable, 0, sizeof (sectable));
-       //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof (uae_u16));
-       mend = bigmfmbuf + length;
-       mend -= (4 + 16 + 8 + 512);
-
-       while (secwritten < drvsec) {
-               int trackoffs;
-
-               for (;;) {
-                       rotateonebit (bigmfmbuf, mend, 1);
-                       if (getmfmword (mbuf) == 0)
-                               break;
-                       if (secwritten == 10) {
-                               mbuf[0] = 0x44;
-                               mbuf[1] = 0x89;
-                       }
-//                     check_offset++;
-                       if (check_offset > 7) {
-                               check_offset = 0;
-                               mbuf++;
-                               if (mbuf >= mend || *mbuf == 0)
-                                       break;
-                       }
-                       if (getmfmword (mbuf) == 0x4489)
-                               break;
-               }
-               if (mbuf >= mend || *mbuf == 0)
-                       break;
-
-               rotateonebit (bigmfmbuf, mend, check_offset);
-               check_offset = 0;
-               mbuf2 = mbuf;
-
-               while (getmfmword (mbuf) == 0x4489)
-                       mbuf+= 1 * 2;
-
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               id = (odd << 1) | even;
-
-               trackoffs = (id & 0xff00) >> 8;
-               if (trackoffs + 1 > drvsec) {
-                       debuglog("illegal sector offset %d\n",trackoffs);
-                       ok = 0;
-                       mbuf = mbuf2;
-                       continue;
-               }
-               if ((id >> 24) != 0xff) {
-                       debuglog ("sector %d format type %02.2X?\n", trackoffs, id >> 24);
-                       ok = 0;
-               }
-               chksum = odd ^ even;
-               slabel = 0;
-               for (i = 0; i < 4; i++) {
-                       odd = getmfmlong (mbuf);
-                       even = getmfmlong (mbuf + 8 * 2);
-                       mbuf += 2* 2;
-
-                       dlong = (odd << 1) | even;
-                       if (dlong) slabel = 1;
-                       chksum ^= odd ^ even;
-               }
-               mbuf += 8 * 2;
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               if (((odd << 1) | even) != chksum) {
-                       debuglog("sector %d header crc error\n", trackoffs);
-                       ok = 0;
-                       mbuf = mbuf2;
-                       continue;
-               }
-               debuglog("sector %d header crc ok\n", trackoffs);
-               if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) {
-                       debuglog("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000) >> 16);
-                       ok++;
-                       mbuf = mbuf2;
-                       continue;
-               }
-               odd = getmfmlong (mbuf);
-               even = getmfmlong (mbuf + 2 * 2);
-               mbuf += 4 * 2;
-               chksum = (odd << 1) | even;
-               secdata = secbuf + 32;
-               for (i = 0; i < 128; i++) {
-                       odd = getmfmlong (mbuf);
-                       even = getmfmlong (mbuf + 256 * 2);
-                       mbuf += 2 * 2;
-                       dlong = (odd << 1) | even;
-                       *secdata++ = (uae_u8) (dlong >> 24);
-                       *secdata++ = (uae_u8) (dlong >> 16);
-                       *secdata++ = (uae_u8) (dlong >> 8);
-                       *secdata++ = (uae_u8) dlong;
-                       chksum ^= odd ^ even;
-               }
-               mbuf += 256 * 2;
-               if (chksum) {
-                       debuglog("sector %d data checksum error\n",trackoffs);
-                       ok = 0;
-               } else if (sectable[trackoffs]) {
-                       debuglog("sector %d already found?\n", trackoffs);
-                       mbuf = mbuf2;
-               } else {
-                       debuglog("sector %d ok\n",trackoffs);
-                       if (slabel) debuglog("(non-empty sector header)\n");
-                       sectable[trackoffs] = 1;
-                       secwritten++;
-                       if (trackoffs == 9)
-                               mbuf += 0x228;
-               }
-       }
-       for (i = 0; i < drvsec; i++) {
-               if (!sectable[i]) {
-                       debuglog ("sector %d missing\n", i);
-                       ok = 0;
-               }
-       }
-       return ok;
-}
-
-static void amiga_data_raw (FDI *fdi, uae_u8 *secbuf, uae_u8 *crc, int len)
-{
-       int i;
-       uae_u8 crcbuf[4];
-
-       if (!crc) {
-               memset (crcbuf, 0, 4);
-       } else {
-               memcpy (crcbuf, crc ,4);
-       }
-       for (i = 0; i < 4; i++)
-               byte_mfm_add (fdi, crcbuf[i]);
-       for (i = 0; i < len; i++)
-               byte_mfm_add (fdi, secbuf[i]);
-}
-
-static void amiga_data (FDI *fdi, uae_u8 *secbuf)
-{
-       uae_u16 mfmbuf[4 + 512];
-       uae_u32 dodd, deven, dck;
-       int i;
-
-       for (i = 0; i < 512; i += 4) {
-               deven = ((secbuf[i + 0] << 24) | (secbuf[i + 1] << 16)
-                | (secbuf[i + 2] << 8) | (secbuf[i + 3]));
-               dodd = deven >> 1;
-               deven &= 0x55555555;
-               dodd &= 0x55555555;
-               mfmbuf[(i >> 1) + 4] = (uae_u16) (dodd >> 16);
-               mfmbuf[(i >> 1) + 5] = (uae_u16) dodd;
-               mfmbuf[(i >> 1) + 256 + 4] = (uae_u16) (deven >> 16);
-               mfmbuf[(i >> 1) + 256 + 5] = (uae_u16) deven;
-       }
-       dck = 0;
-       for (i = 4; i < 4 + 512; i += 2)
-               dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-       deven = dodd = dck;
-       dodd >>= 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[0] = (uae_u16) (dodd >> 16);
-       mfmbuf[1] = (uae_u16) dodd;
-       mfmbuf[2] = (uae_u16) (deven >> 16);
-       mfmbuf[3] = (uae_u16) deven;
-
-       for (i = 0; i < 4 + 512; i ++)
-               word_post_mfm_add (fdi, mfmbuf[i]);
-}
-
-static void amiga_sector_header (FDI *fdi, uae_u8 *header, uae_u8 *data, int sector, int untilgap)
-{
-       uae_u8 headerbuf[4], databuf[16];
-       uae_u32 deven, dodd, hck;
-       uae_u16 mfmbuf[24];
-       int i;
-
-       byte_mfm_add (fdi, 0);
-       byte_mfm_add (fdi, 0);
-       word_add (fdi, 0x4489);
-       word_add (fdi, 0x4489);
-       if (header) {
-               memcpy (headerbuf, header, 4);
-       } else {
-               headerbuf[0] = 0xff;
-               headerbuf[1] = (uae_u8)fdi->current_track;
-               headerbuf[2] = (uae_u8)sector;
-               headerbuf[3] = (uae_u8)untilgap;
-       }
-       if (data)
-               memcpy (databuf, data, 16);
-       else
-               memset (databuf, 0, 16);
-
-       deven = ((headerbuf[0] << 24) | (headerbuf[1] << 16)
-               | (headerbuf[2] << 8) | (headerbuf[3]));
-       dodd = deven >> 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[0] = (uae_u16) (dodd >> 16);
-       mfmbuf[1] = (uae_u16) dodd;
-       mfmbuf[2] = (uae_u16) (deven >> 16);
-       mfmbuf[3] = (uae_u16) deven;
-       for (i = 0; i < 16; i += 4) {
-               deven = ((databuf[i] << 24) | (databuf[i + 1] << 16)
-                       | (databuf[i + 2] << 8) | (databuf[i + 3]));
-               dodd = deven >> 1;
-               deven &= 0x55555555;
-               dodd &= 0x55555555;
-               mfmbuf[(i >> 1) + 0 + 4] = (uae_u16) (dodd >> 16);
-               mfmbuf[(i >> 1) + 0 + 5] = (uae_u16) dodd;
-               mfmbuf[(i >> 1) + 8 + 4] = (uae_u16) (deven >> 16);
-               mfmbuf[(i >> 1) + 8 + 5] = (uae_u16) deven;
-       }
-       hck = 0;
-       for (i = 0; i < 4 + 16; i += 2)
-               hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-       deven = dodd = hck;
-       dodd >>= 1;
-       deven &= 0x55555555;
-       dodd &= 0x55555555;
-       mfmbuf[20] = (uae_u16) (dodd >> 16);
-       mfmbuf[21] = (uae_u16) dodd;
-       mfmbuf[22] = (uae_u16) (deven >> 16);
-       mfmbuf[23] = (uae_u16) deven;
-
-       for (i = 0; i < 4 + 16 + 4; i ++)
-               word_post_mfm_add (fdi, mfmbuf[i]);
-}
-
-/* standard super-extended Amiga sector header */
-static void s20(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16)); 
-       amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0);
-       fdi->track_src += 4 + 16;
-}
-/* standard extended Amiga sector header */
-static void s21(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s21:header=%s", datalog(fdi->track_src, 4)); 
-       amiga_sector_header (fdi, fdi->track_src, 0, 0, 0);
-       fdi->track_src += 4;
-}
-/* standard Amiga sector header */
-static void s22(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
-       amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]);
-       fdi->track_src += 2;
-}
-/* standard 512-byte, CRC-correct Amiga data */
-static void s23(FDI *fdi)
-{
-       debuglog("s23:data=%s", datalog (fdi->track_src, 512));
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-/* not-decoded, 128*2^x-byte, CRC-correct Amiga data */
-static void s24(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
-       amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift;
-}
-/* not-decoded, 128*2^x-byte, CRC-incorrect Amiga data */
-static void s25(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
-       amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift);
-       fdi->track_src += 4 + (128 << shift);
-}
-/* standard extended Amiga sector */
-static void s26(FDI *fdi)
-{
-       s21 (fdi);
-       debuglog("s26:data=%s", datalog (fdi->track_src, 512));
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-/* standard short Amiga sector */
-static void s27(FDI *fdi)
-{
-       s22 (fdi);
-       debuglog("s27:data=%s", datalog (fdi->track_src, 512));
-       amiga_data (fdi, fdi->track_src);
-       fdi->track_src += 512;
-}
-
-/* *** */
-/* IBM */
-/* *** */
-
-static uae_u16 ibm_crc (uae_u8 byte, int reset)
-{
-       static uae_u16 crc;
-       int i;
-
-       if (reset) crc = 0xcdb4;
-       for (i = 0; i < 8; i++) {
-               if (crc & 0x8000) {
-                       crc <<= 1;
-                       if (!(byte & 0x80)) crc ^= 0x1021;
-               } else {
-                       crc <<= 1;
-                       if (byte & 0x80) crc ^= 0x1021;
-               }
-               byte <<= 1;
-       }
-       return crc;
-}
-
-static void ibm_data (FDI *fdi, uae_u8 *data, uae_u8 *crc, int len)
-{
-       int i;
-       uae_u8 crcbuf[2];
-       uae_u16 crcv;
-
-       word_add (fdi, 0x4489);
-       word_add (fdi, 0x4489);
-       word_add (fdi, 0x4489);
-       byte_mfm_add (fdi, 0xfb);
-       ibm_crc (0xfb, 1);
-       for (i = 0; i < len; i++) {
-               byte_mfm_add (fdi, data[i]);
-               crcv = ibm_crc (data[i], 0);
-       }
-       if (!crc) {
-               crc = crcbuf;
-               crc[0] = (uae_u8)(crcv >> 8);
-               crc[1] = (uae_u8)crcv;
-       }
-       byte_mfm_add (fdi, crc[0]);
-       byte_mfm_add (fdi, crc[1]);
-}
-
-static void ibm_sector_header (FDI *fdi, uae_u8 *data, uae_u8 *crc, int secnum, int pre)
-{
-       uae_u8 secbuf[5];
-       uae_u8 crcbuf[2];
-       uae_u16 crcv;
-       int i;
-
-       if (pre)
-               bytes_mfm_add (fdi, 0, 12);
-       word_add (fdi, 0x4489);
-       word_add (fdi, 0x4489);
-       word_add (fdi, 0x4489);
-       secbuf[0] = 0xfe;
-       if (secnum >= 0) {
-               secbuf[1] = (uae_u8)(fdi->current_track/2);
-               secbuf[2] = (uae_u8)(fdi->current_track%2);
-               secbuf[3] = (uae_u8)secnum;
-               secbuf[4] = 2;
-       } else {
-               memcpy (secbuf + 1, data, 4);
-       }
-       ibm_crc (secbuf[0], 1);
-       ibm_crc (secbuf[1], 0);
-       ibm_crc (secbuf[2], 0);
-       ibm_crc (secbuf[3], 0);
-       crcv = ibm_crc (secbuf[4], 0);
-       if (crc) {
-               memcpy (crcbuf, crc, 2);
-       } else {
-               crcbuf[0] = (uae_u8)(crcv >> 8);
-               crcbuf[1] = (uae_u8)crcv;
-       }
-       /* data */
-       for (i = 0;i < 5; i++)
-               byte_mfm_add (fdi, secbuf[i]);
-       /* crc */
-       byte_mfm_add (fdi, crcbuf[0]);
-       byte_mfm_add (fdi, crcbuf[1]);
-}
-
-/* standard IBM index address mark */
-static void s10(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0, 12);
-       word_add (fdi, 0x5224);
-       word_add (fdi, 0x5224);
-       word_add (fdi, 0x5224);
-       byte_mfm_add (fdi, 0xfc);
-}
-/* standard IBM pre-gap */
-static void s11(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0x4e, 78);
-       bit_dedrop (fdi);
-       s10 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 50);
-}
-/* standard ST pre-gap */
-static void s12(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       bytes_mfm_add (fdi, 0x4e, 78);
-}
-/* standard extended IBM sector header */
-static void s13(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s13:header=%s", datalog (fdi->track_src, 4));
-       ibm_sector_header (fdi, fdi->track_src, 0, -1, 1);
-       fdi->track_src += 4;
-}
-/* standard mini-extended IBM sector header */
-static void s14(FDI *fdi)
-{
-       debuglog ("s14:header=%s", datalog (fdi->track_src, 4));
-       ibm_sector_header (fdi, fdi->track_src, 0, -1, 0);
-       fdi->track_src += 4;
-}
-/* standard short IBM sector header */
-static void s15(FDI *fdi)
-{
-       bit_drop_next (fdi);
-       debuglog ("s15:sector=%d", *fdi->track_src);
-       ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1);
-}
-/* standard mini-short IBM sector header */
-static void s16(FDI *fdi)
-{
-       debuglog ("s16:track=%d", *fdi->track_src);
-       ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0);
-}
-/* standard CRC-incorrect mini-extended IBM sector header */
-static void s17(FDI *fdi)
-{
-       debuglog ("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
-       ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0);
-       fdi->track_src += 4 + 2;
-}
-/* standard CRC-incorrect mini-short IBM sector header */
-static void s18(FDI *fdi)
-{
-       debuglog ("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4));
-       ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0);
-       fdi->track_src += 1 + 4;
-}
-/* standard 512-byte CRC-correct IBM data */
-static void s19(FDI *fdi)
-{
-       debuglog ("s19:data=%s", datalog (fdi->track_src , 512));
-       ibm_data (fdi, fdi->track_src, 0, 512);
-       fdi->track_src += 512;
-}
-/* standard 128*2^x-byte-byte CRC-correct IBM data */
-static void s1a(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog ("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
-       ibm_data (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift;
-}
-/* standard 128*2^x-byte-byte CRC-incorrect IBM data */
-static void s1b(FDI *fdi)
-{
-       int shift = *fdi->track_src++;
-       debuglog ("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift));
-       ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift);
-       fdi->track_src += (128 << shift) + 2;
-}
-/* standard extended IBM sector */
-static void s1c(FDI *fdi)
-{
-       int shift = fdi->track_src[3];
-       s13 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 22);
-       bytes_mfm_add (fdi, 0x00, 12);
-       ibm_data (fdi, fdi->track_src, 0, 128 << shift);
-       fdi->track_src += 128 << shift;
-}
-/* standard short IBM sector */
-static void s1d(FDI *fdi)
-{
-       s15 (fdi);
-       bytes_mfm_add (fdi, 0x4e, 22);
-       bytes_mfm_add (fdi, 0x00, 12);
-       s19 (fdi);
-}
-
-/* end marker */
-static void sff(FDI *fdi)
-{
-}
-
-typedef void (*decode_described_track_func)(FDI*);
-
-static decode_described_track_func decode_sectors_described_track[] =
-{
-       s00,s01,s02,s03,s04,dxx,dxx,dxx,s08,s09,s0a,s0b,s0c,s0d,dxx,dxx, /* 00-0F */
-       s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s1a,s1b,s1c,s1d,dxx,dxx, /* 10-1F */
-       s20,s21,s22,s23,s24,s25,s26,s27,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 20-2F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 30-3F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 40-4F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 50-5F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 60-6F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 70-7F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 80-8F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 90-9F */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* A0-AF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* B0-BF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* C0-CF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* D0-DF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* E0-EF */
-       dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,sff  /* F0-FF */
-};
-
-static void track_amiga (struct fdi *fdi, int first_sector, int max_sector)
-{
-       int i;
-
-       bit_add (fdi, 0);
-       bit_drop_next (fdi);
-       for (i = 0; i < max_sector; i++) {
-               amiga_sector_header (fdi, 0, 0, first_sector, max_sector - i);
-               amiga_data (fdi, fdi->track_src + first_sector * 512);
-               first_sector++;
-               if (first_sector >= max_sector) first_sector = 0;
-       }
-       bytes_mfm_add (fdi, 0, 260); /* gap */
-}
-static void track_atari_st (struct fdi *fdi, int max_sector)
-{
-       int i, gap3;
-       uae_u8 *p = fdi->track_src;
-
-       switch (max_sector)
-               {
-               case 9:
-               gap3 = 40;
-               break;
-               case 10:
-               gap3 = 24;
-               break;
-       }
-       s15 (fdi);
-       for (i = 0; i < max_sector; i++) {
-               byte_mfm_add (fdi, 0x4e);
-               byte_mfm_add (fdi, 0x4e);
-               ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
-               ibm_data (fdi, p + i * 512, 0, 512);
-               bytes_mfm_add (fdi, 0x4e, gap3);
-       }
-       bytes_mfm_add (fdi, 0x4e, 660 - gap3);
-       fdi->track_src += fdi->track_len * 256;
-}
-static void track_pc (struct fdi *fdi, int max_sector)
-{
-       int i, gap3;
-       uae_u8 *p = fdi->track_src;
-
-       switch (max_sector)
-               {
-               case 8:
-               gap3 = 116;
-               break;
-               case 9:
-               gap3 = 54;
-               break;
-               default:
-               gap3 = 100; /* fixme */
-               break;
-       }
-       s11 (fdi);
-       for (i = 0; i < max_sector; i++) {
-               byte_mfm_add (fdi, 0x4e);
-               byte_mfm_add (fdi, 0x4e);
-               ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
-               ibm_data (fdi, p + i * 512, 0, 512);
-               bytes_mfm_add (fdi, 0x4e, gap3);
-       }
-       bytes_mfm_add (fdi, 0x4e, 600 - gap3);
-       fdi->track_src += fdi->track_len * 256;
-}
-
-/* amiga dd */
-static void track_amiga_dd (struct fdi *fdi)
-{
-       uae_u8 *p = fdi->track_src;
-       track_amiga (fdi, fdi->track_len >> 4, 11);
-       fdi->track_src = p + (fdi->track_len & 15) * 512;
-}
-/* amiga hd */
-static void track_amiga_hd (struct fdi *fdi)
-{
-       uae_u8 *p = fdi->track_src;
-       track_amiga (fdi, 0, 22);
-       fdi->track_src = p + fdi->track_len * 256;
-}
-/* atari st 9 sector */
-static void track_atari_st_9 (struct fdi *fdi)
-{
-       track_atari_st (fdi, 9);
-}
-/* atari st 10 sector */
-static void track_atari_st_10 (struct fdi *fdi)
-{
-       track_atari_st (fdi, 10);
-}
-/* pc 8 sector */
-static void track_pc_8 (struct fdi *fdi)
-{
-       track_pc (fdi, 8);
-}
-/* pc 9 sector */
-static void track_pc_9 (struct fdi *fdi)
-{
-       track_pc (fdi, 9);
-}
-/* pc 15 sector */
-static void track_pc_15 (struct fdi *fdi)
-{
-       track_pc (fdi, 15);
-}
-/* pc 18 sector */
-static void track_pc_18 (struct fdi *fdi)
-{
-       track_pc (fdi, 18);
-}
-/* pc 36 sector */
-static void track_pc_36 (struct fdi *fdi)
-{
-       track_pc (fdi, 36);
-}
-
-typedef void (*decode_normal_track_func)(FDI*);
-
-static decode_normal_track_func decode_normal_track[] =
-{ 
-       track_empty, /* 0 */
-       track_amiga_dd, track_amiga_hd, /* 1-2 */
-       track_atari_st_9, track_atari_st_10, /* 3-4 */
-       track_pc_8, track_pc_9, track_pc_15, track_pc_18, track_pc_36, /* 5-9 */
-       zxx,zxx,zxx,zxx,zxx /* A-F */
-};
-
-static void fix_mfm_sync (FDI *fdi)
-{
-       int i, pos, off1, off2, off3, mask1, mask2, mask3;
-
-       for (i = 0; i < fdi->mfmsync_offset; i++) {
-               pos = fdi->mfmsync_buffer[i];
-               off1 = (pos - 1) >> 3;
-               off2 = (pos + 1) >> 3;
-               off3 = pos >> 3;
-               mask1 = 1 << (7 - ((pos - 1) & 7));
-               mask2 = 1 << (7 - ((pos + 1) & 7));
-               mask3 = 1 << (7 - (pos & 7));
-               if (!(fdi->track_dst[off1] & mask1) && !(fdi->track_dst[off2] & mask2))
-                       fdi->track_dst[off3] |= mask3;
-               else
-                       fdi->track_dst[off3] &= ~mask3;
-       }
-}
-
-static int handle_sectors_described_track (FDI *fdi)
-{
-       int oldout;
-       uae_u8 *start_src = fdi->track_src ;
-       fdi->encoding_type = *fdi->track_src++;
-       fdi->index_offset = get_u32(fdi->track_src);
-       fdi->index_offset >>= 8;
-       fdi->track_src += 3;
-       outlog ("sectors_described, index offset: %d\n",fdi->index_offset);
-
-       do {
-               fdi->track_type = *fdi->track_src++;
-               outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
-               oldout = fdi->out;
-               decode_sectors_described_track[fdi->track_type](fdi);
-               outlog(" %d\n", fdi->out - oldout);
-               oldout = fdi->out;
-               if (fdi->out < 0 || fdi->err) {
-                       outlog ("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
-                       return -1;
-               }
-               if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) {
-                       outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
-                       return -1;
-               }
-       } while (fdi->track_type != 0xff);
-       outlog("\n");
-       fix_mfm_sync (fdi);
-       return fdi->out;
-}
-
-static uae_u8 *fdi_decompress (int pulses, uae_u8 *sizep, uae_u8 *src, int *dofree)
-{
-       uae_u32 size = get_u24 (sizep);
-       uae_u32 *dst2;
-       int len = size & 0x3fffff;
-       uae_u8 *dst;
-       int mode = size >> 22, i;
-
-       *dofree = 0;
-       if (mode == 0 && pulses * 2 > len)
-               mode = 1;
-       if (mode == 0) {
-               dst2 = (uae_u32*)src;
-               for (i = 0; i < pulses; i++) {
-                       *dst2++ = get_u32 (src);                        
-                       src += 4;
-               }
-               dst = src;
-       } else if (mode == 1) {
-               dst = fdi_malloc (pulses *4);
-               *dofree = 1;
-               fdi_decode (src, pulses, dst);
-       } else {
-               dst = 0;
-       }
-       return dst;
-}
-
-static void dumpstream(int track, uae_u8 *stream, int len)
-{
-    char name[100];
-    FILE *f;
-
-    sprintf (name, "track_%d.raw", track);
-    f = fopen(name, "wb");
-    fwrite (stream, 1, len * 4, f);
-    fclose (f);
-}    
-
-static int bitoffset;
-
-STATIC_INLINE void addbit (uae_u8 *p, int bit)
-{
-       int off1 = bitoffset / 8;
-       int off2 = bitoffset % 8;
-       p[off1] |= bit << (7 - off2);
-       bitoffset++;
-}
-
-
-struct pulse_sample {
-       unsigned long size;
-       int number_of_bits;
-};
-
-#define FDI_MAX_ARRAY 6 /* change this value as you want */
-static int pulse_limitval = 20;
-static struct pulse_sample psarray[FDI_MAX_ARRAY];
-static int array_index;
-static unsigned long total;
-static int totaldiv;
-
-static void init_array(unsigned long standard_MFM_2_bit_cell_size)
-{
-       int i;
-       
-       for (i = 0; i < FDI_MAX_ARRAY; i++) {
-               psarray[i].size = standard_MFM_2_bit_cell_size; // That is (total track length / 50000) for Amiga double density
-               total += psarray[i].size;
-               psarray[i].number_of_bits = 2;
-               totaldiv += psarray[i].number_of_bits;
-       }
-       array_index = 0;
-}
-
-static void fdi2_mfm_decode(FDI *fdi, unsigned long totalavg, uae_u32 *avgp, uae_u8 *idx, int idx_off1, int idx_off2, int idx_off3, int maxidx, int pulses)
-{
-       unsigned long adjust;
-       unsigned long adjusted_pulse;
-       unsigned long standard_MFM_2_bit_cell_size = totalavg / 50000;
-       int real_size, i, j;
-       uae_u8 *d = fdi->track_dst_buffer;
-       uae_u16 *pt = fdi->track_dst_buffer_timing;
-
-       adjust = 0;
-       total = 0;
-       totaldiv = 0;
-       init_array(standard_MFM_2_bit_cell_size);
-       bitoffset = 0;
-       for (i = 0; i < pulses; i++)
-       {
-               if (idx[idx_off1] + idx[idx_off2] >= maxidx) {
-                       uae_u32 pulse = avgp[i];
-                       uae_u32 avg_size = total / totaldiv; /* this is the new average size for one MFM bit */
-                       /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
-                       if ((avg_size < ((standard_MFM_2_bit_cell_size / 2) - (pulse_limitval * standard_MFM_2_bit_cell_size / 200))) ||
-                               (avg_size > ((standard_MFM_2_bit_cell_size / 2) + (pulse_limitval * standard_MFM_2_bit_cell_size /200))))
-                                       init_array(standard_MFM_2_bit_cell_size); 
-                               /* this is to prevent the average value from going too far
-                               * from the theoretical value, otherwise it could progressively go to (2 *
-                               * real value), or (real value / 2), etc. */
-                       if ((pulse > adjust) && (adjust < avg_size))
-                               adjusted_pulse = pulse - adjust;
-                       else
-                               adjusted_pulse = pulse;
-                       adjusted_pulse = pulse;
-                       real_size = 1;
-                       do {
-                               addbit (d, 0);
-                               real_size++;
-                       } while (adjusted_pulse > avg_size * real_size + avg_size / 2);
-                       addbit (d, 1);
-#if 1
-                       for (j = 0; j < real_size; j++)
-                               *pt++ = (uae_u16)(adjusted_pulse / real_size);
-#endif
-                       /* Note that you should also consider values above 4! Too lazy to do it here ;-) */
-                       adjust = (real_size * avg_size) - pulse;
-                       /* function to transform the value in real_size to '01', '001' or '0001', and append this to the decoded MFM stream */
-                       total -= psarray[array_index].size;
-                       totaldiv -= psarray[array_index].number_of_bits;
-                       psarray[array_index].size = pulse;
-                       psarray[array_index].number_of_bits = real_size;
-                       total += pulse;
-                       totaldiv += real_size;
-                       array_index++;
-                       if (array_index >= FDI_MAX_ARRAY)
-                               array_index = 0;
-               }
-               idx += idx_off3;
-       }
-       fdi->out = bitoffset;
-       write_log ("result bits: %d\n", bitoffset);
-}
-
-static void fdi2_celltiming (FDI *fdi, unsigned long totalavg, int bitoffset)
-{
-       uae_u16 *pt2, *pt;
-       double avg_bit_len;
-       int timed = 0;
-       int i;
-
-       avg_bit_len = (double)totalavg / (double)bitoffset;
-       pt2 = pt = fdi->track_dst_buffer_timing;
-       for (i = 0; i < bitoffset / 8; i++) {
-               double v = (pt2[0] + pt2[1] + pt2[2] + pt2[3] + pt2[4] + pt2[5] + pt2[6] + pt2[7]) / 8.0;
-               uae_u16 vv;
-               v = 1000.0 * v / avg_bit_len;
-               vv = (uae_u16)v;
-               *pt++ = vv;
-               if (vv > 1030 || vv < 970)
-                       timed = 1;
-               pt2 += 8;
-               if (vv > 1030 || vv < 970)
-                       write_log ("%d ", vv);
-       }
-       *pt++ = fdi->track_dst_buffer_timing[0];
-       *pt = fdi->track_dst_buffer_timing[0];
-       if (!timed)
-               fdi->track_dst_buffer_timing[0] = 0;
-}
-
-static int decode_lowlevel_track (FDI *fdi, int *indexoffsetp, int track)
-{
-       uae_u8 *p1, *d;
-       uae_u32 *p2;
-       uae_u32 *avgp, *minp = 0, *maxp = 0;
-       uae_u8 *idxp = 0;
-       uae_u32 maxidx, minidx, totalavg, weakbits;
-       int i, len, pulses, indexoffset;
-       int avg_free, min_free = 0, max_free = 0, idx_free;
-       int idx_off1, idx_off2, idx_off3;
-
-       d = fdi->track_dst;
-       p1 = fdi->track_src;
-       pulses = get_u32 (p1);
-       if (!pulses)
-               return -1;
-       p1 += 4;
-       len = 12;
-       avgp = (uae_u32*)fdi_decompress (pulses, p1 + 0, p1 + len, &avg_free);
-       //dumpstream(track, (uae_u8*)avgp, pulses);
-       len += get_u24 (p1 + 0) & 0x3fffff;
-       if (!avgp)
-               return -1;
-       if (get_u24 (p1 + 3) && get_u24 (p1 + 6)) {
-#if 0
-               minp = (uae_u32*)fdi_decompress (pulses, p1 + 3, p1 + len, &min_free);
-#endif
-               len += get_u24 (p1 + 3) & 0x3fffff;
-#if 0
-               maxp = (uae_u32*)fdi_decompress (pulses, p1 + 6, p1 + len, &max_free);
-#endif
-               len += get_u24 (p1 + 6) & 0x3fffff;
-       }
-       if (get_u24 (p1 + 9)) {
-               idx_off1 = 0;
-               idx_off2 = 1;
-               idx_off3 = 2;
-               idxp = fdi_decompress (pulses, p1 + 9, p1 + len, &idx_free);
-               if (idx_free) {
-                       if (idxp[0] == 0 && idxp[1] == 0) {
-                               idx_off1 = 2;
-                               idx_off2 = 3;
-                       } else {
-                               idx_off1 = 1;
-                               idx_off2 = 0;
-                       }
-                       idx_off3 = 4;
-               }
-       } else {
-               idxp = fdi_malloc (pulses * 2);
-               idx_free = 1;
-               for (i = 0; i < pulses; i++) {
-                       idxp[i * 2 + 0] = 2;
-                       idxp[i * 2 + 1] = 0;
-               }
-               idxp[0] = 1;
-               idxp[1] = 1;
-       }
-
-       maxidx = 0;
-       minidx = 255;
-       indexoffset = 0;
-       p1 = idxp;
-       for (i = 0; i < pulses; i++) {
-               if (p1[idx_off1] + p1[idx_off2] > maxidx)
-                       maxidx = p1[idx_off1] + p1[idx_off2];
-               if (abs (p1[idx_off1] - p1[idx_off2]) < minidx) {
-                       minidx = abs (p1[idx_off1] - p1[idx_off2]);
-                       indexoffset = i;
-               }
-               p1 += idx_off3;
-       }
-       p1 = idxp;
-       p2 = avgp;
-       totalavg = 0;
-       weakbits = 0;
-       for (i = 0; i < pulses; i++) {
-               if (p1[idx_off1] + p1[idx_off2] >= maxidx) {
-                       totalavg += *p2;
-               } else {
-                       weakbits++;
-               }
-               p2++;
-               p1 += idx_off3;
-       }
-       len = totalavg / 100000;
-       outlog("totalavg=%d index=%d maxidx=%d weakbits=%d len=%d\n",
-               totalavg, indexoffset, maxidx, weakbits, len);
-       fdi2_mfm_decode (fdi, totalavg, avgp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses);
-       outlog("number of bits=%d avg len=%.2f\n", bitoffset, (double)totalavg / bitoffset);
-       fdi2_celltiming (fdi, totalavg, bitoffset);
-
-       *indexoffsetp = indexoffset;
-       if (avg_free)
-               fdi_free (avgp);
-       if (min_free)
-               fdi_free (minp);
-       if (max_free)
-               fdi_free (maxp);
-       if (idx_free)
-               fdi_free (idxp);
-       return bitoffset;
-}
-
-static unsigned char fdiid[]={"Formatted Disk Image file"};
-static int bit_rate_table[16] = { 125,150,250,300,500,1000 };
-
-void fdi2raw_header_free (FDI *fdi)
-{
-       int i, j;
-
-       fdi_free (fdi->mfmsync_buffer);
-       fdi_free (fdi->track_src_buffer);
-       fdi_free (fdi->track_dst_buffer);
-       fdi_free (fdi->track_dst_buffer_timing);
-       for (i = 0; i < MAX_TRACKS; i++) {
-               struct fdi_cache *c = &fdi->cache[i];
-               for (j = 0; j < MAX_REVOLUTIONS; j++)
-                       fdi_free (c->cache_buffer[j]);
-               fdi_free (c->cache_buffer_timing);
-       }
-       fdi_free (fdi);
-#ifdef DEBUG
-       write_log ("FREE: memory allocated %d\n", fdi_allocated);
-#endif
-}
-
-int fdi2raw_get_last_track (FDI *fdi)
-{
-       return fdi->last_track;
-}
-
-int fdi2raw_get_num_sector (FDI *fdi)
-{
-       if (fdi->header[152] == 0x02)
-               return 22;
-       return 11;
-}
-
-int fdi2raw_get_last_head (FDI *fdi)
-{
-       return fdi->last_head;
-}
-
-int fdi2raw_get_rotation (FDI *fdi)
-{
-       return fdi->rotation_speed;
-}
-
-int fdi2raw_get_bit_rate (FDI *fdi)
-{
-       return fdi->bit_rate;
-}
-
-int fdi2raw_get_type (FDI *fdi)
-{
-       return fdi->disk_type;
-}
-
-int fdi2raw_get_write_protect (FDI *fdi)
-{
-       return fdi->write_protect;
-}
-
-FDI *fdi2raw_header(struct zfile *f)
-{
-       int i, offset, oldseek;
-       uae_u8 type, size;
-       FDI *fdi;
-
-#ifdef DEBUG
-       write_log ("ALLOC: memory allocated %d\n", fdi_allocated);
-#endif
-       fdi = fdi_malloc(sizeof(FDI));
-       memset (fdi, 0, sizeof (FDI));
-       fdi->file = f;
-       oldseek = zfile_ftell (fdi->file);
-       zfile_fseek (fdi->file, 0, SEEK_SET);
-       zfile_fread (fdi->header, 2048, 1, fdi->file);
-       zfile_fseek (fdi->file, oldseek, SEEK_SET);
-       if (memcmp (fdiid, fdi->header, strlen (fdiid)) ) {
-               fdi_free(fdi);
-               return NULL;
-       }
-       if ((fdi->header[140] != 1 && fdi->header[140] != 2) || fdi->header[141] != 0) {
-               fdi_free(fdi);
-               return NULL;
-       }
-
-       fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
-       fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER);
-       fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER);
-       fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER);
-       
-       fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1;
-       fdi->last_track *= fdi->header[144] + 1;
-       if (fdi->last_track > MAX_TRACKS)
-               fdi->last_track = MAX_TRACKS;
-       fdi->last_head = fdi->header[144];
-       fdi->disk_type = fdi->header[145];
-       fdi->rotation_speed = fdi->header[146] + 128;
-       fdi->write_protect = fdi->header[147] & 1;
-       outlog ("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
-       outlog ("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed);
-
-       offset = 512;
-       i = fdi->last_track;
-       if (i > 180) {
-               offset += 512;
-               i -= 180;
-               while (i > 256) {
-                       offset += 512;
-                       i -= 256;
-               }
-       }
-       for (i = 0; i < fdi->last_track; i++) {
-               fdi->track_offsets[i] = offset;
-               type = fdi->header[152 + i * 2];
-               size = fdi->header[152 + i * 2 + 1];
-               if (type == 1)
-                       offset += (size & 15) * 512;
-               else if ((type & 0xc0) == 0x80)
-                       offset += (((type & 0x3f) << 8) | size) * 256;
-               else
-                       offset += size * 256;
-       }
-       fdi->track_offsets[i] = offset;
-
-       return fdi;
-}
-
-
-int fdi2raw_loadrevolution (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength)
-{
-       return 0;
-}
-
-int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev)
-{
-       uae_u8 *p;
-       int outlen, i, j, indexoffset = 0;
-       struct fdi_cache *cache;
-
-       cache = &fdi->cache[track];
-       if (cache->cache_buffer[0]) {
-               *tracklength = cache->length[0];
-               for (i = 0; i < (tracklength[0] + 15) / (2 * 8); i++) {
-                       uae_u8 *data = cache->cache_buffer[0] + i * 2;
-                       *mfmbuf++ = 256 * *data + *(data + 1);
-               }               
-               if (cache->cache_buffer_timing)
-                       memcpy (tracktiming, cache->cache_buffer_timing, (tracklength[0] + 7) / 8 * sizeof (uae_u16));
-               *indexoffsetp = cache->indexoffset;
-               return 1;
-       }
-               
-       fdi->err = 0;
-       fdi->track_src_len = fdi->track_offsets[track + 1] - fdi->track_offsets[track];
-       zfile_fseek (fdi->file, fdi->track_offsets[track], SEEK_SET);
-       zfile_fread (fdi->track_src_buffer, fdi->track_src_len, 1, fdi->file);
-       memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
-       fdi->track_dst_buffer_timing[0] = 0;
-
-       fdi->current_track = track;
-       fdi->track_src = fdi->track_src_buffer;
-       fdi->track_dst = fdi->track_dst_buffer;
-       p = fdi->header + 152 + fdi->current_track * 2;
-       fdi->track_type = *p++;
-       fdi->track_len = *p++;
-       fdi->bit_rate = 0;
-       fdi->out = 0;
-       fdi->mfmsync_offset = 0;
-
-       if ((fdi->track_type & 0xf0) == 0xf0 || (fdi->track_type & 0xf0) == 0xe0)
-               fdi->bit_rate = bit_rate_table[fdi->track_type & 0x0f];
-       else
-               fdi->bit_rate = 250;
-
-       outlog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
-               fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate);
-
-       if ((fdi->track_type & 0xc0) == 0x80) {
-
-               outlen = decode_lowlevel_track (fdi, &indexoffset, track);
-
-       } else if ((fdi->track_type & 0xf0) == 0xf0) {
-
-               outlen = decode_raw_track (fdi);
-
-       } else if ((fdi->track_type & 0xf0) == 0xe0) {
-
-               outlen = handle_sectors_described_track (fdi);
-
-       } else if ((fdi->track_type & 0xf0)) {
-
-               zxx (fdi);
-               outlen = -1;
-               
-       } else if (fdi->track_type < 0x10) {
-
-               decode_normal_track[fdi->track_type](fdi);
-               fix_mfm_sync (fdi);
-               outlen = fdi->out;
-
-       } else {
-
-               zxx (fdi);
-               outlen = -1;
-
-       }
-
-       if (fdi->err)
-               return 0;
-
-       if (outlen > 0) {
-               for (j = 0; j < MAX_REVOLUTIONS; j++) {
-                       fdi_free (cache->cache_buffer[j]);
-                       cache->cache_buffer[j] = 0;
-               }
-               fdi_free (cache->cache_buffer_timing);
-               cache->cache_buffer_timing = 0;
-               cache->indexoffset = indexoffset;
-               cache->length[0] = outlen;
-               cache->cache_buffer[0] = fdi_malloc ((outlen + 7) / 8);
-               memcpy (cache->cache_buffer[0], fdi->track_dst_buffer, (outlen + 7) / 8);
-               if (fdi->track_dst_buffer_timing[0] > 0) {
-                       cache->cache_buffer_timing = fdi_malloc ((outlen + 7) / 8 * sizeof (uae_u16));
-                       memcpy (cache->cache_buffer_timing, fdi->track_dst_buffer_timing, (outlen + 7) / 8 * sizeof (uae_u16));
-               }
-               return fdi2raw_loadtrack (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev);
-       }
-       return 0;
-}
-
index 6d39ab97b841b2da3389ebfcbe1b7f0a223a067b..792e075aec5f8fbd51a68fc32581a86ca4e68b54 100755 (executable)
@@ -119,255 +119,255 @@ struct customData custd[] =
 #if 0
     { "BLTDDAT",  0xdff000 }, /* Blitter dest. early read (dummy address) */
 #endif
-    { "DMACONR",  0xdff002 }, /* Dma control (and blitter status) read */
-    { "VPOSR",    0xdff004 }, /* Read vert most sig. bits (and frame flop */
-    { "VHPOSR",   0xdff006 }, /* Read vert and horiz position of beam */
+    { "DMACONR",  0xdff002, 1, 0 }, /* Dma control (and blitter status) read */
+    { "VPOSR",    0xdff004, 1, 0 }, /* Read vert most sig. bits (and frame flop */
+    { "VHPOSR",   0xdff006, 1, 0 }, /* Read vert and horiz position of beam */
 #if 0
     { "DSKDATR",  0xdff008 }, /* Disk data early read (dummy address) */
 #endif
-    { "JOY0DAT",  0xdff00A }, /* Joystick-mouse 0 data (vert,horiz) */
-    { "JOT1DAT",  0xdff00C }, /* Joystick-mouse 1 data (vert,horiz) */
-    { "CLXDAT",   0xdff00E }, /* Collision data reg. (read and clear) */
-    { "ADKCONR",  0xdff010 }, /* Audio,disk control register read */
-    { "POT0DAT",  0xdff012 }, /* Pot counter pair 0 data (vert,horiz) */
-    { "POT1DAT",  0xdff014 }, /* Pot counter pair 1 data (vert,horiz) */
-    { "POTGOR",   0xdff016 }, /* Pot pin data read */
-    { "SERDATR",  0xdff018 }, /* Serial port data and status read */
-    { "DSKBYTR",  0xdff01A }, /* Disk data byte and status read */
-    { "INTENAR",  0xdff01C }, /* Interrupt enable bits read */
-    { "INTREQR",  0xdff01E }, /* Interrupt request bits read */
-    { "DSKPTH",   0xdff020 }, /* Disk pointer (high 5 bits) */
-    { "DSKPTL",   0xdff022 }, /* Disk pointer (low 15 bits) */
-    { "DSKLEN",   0xdff024 }, /* Disk lentgh */
-    { "DSKDAT",   0xdff026 }, /* Disk DMA data write */
+    { "JOY0DAT",  0xdff00A, 1, 0 }, /* Joystick-mouse 0 data (vert,horiz) */
+    { "JOT1DAT",  0xdff00C, 1, 0 }, /* Joystick-mouse 1 data (vert,horiz) */
+    { "CLXDAT",   0xdff00E, 1, 0 }, /* Collision data reg. (read and clear) */
+    { "ADKCONR",  0xdff010, 1, 0 }, /* Audio,disk control register read */
+    { "POT0DAT",  0xdff012, 1, 0 }, /* Pot counter pair 0 data (vert,horiz) */
+    { "POT1DAT",  0xdff014, 1, 0 }, /* Pot counter pair 1 data (vert,horiz) */
+    { "POTGOR",   0xdff016, 1, 0 }, /* Pot pin data read */
+    { "SERDATR",  0xdff018, 1, 0 }, /* Serial port data and status read */
+    { "DSKBYTR",  0xdff01A, 1, 0 }, /* Disk data byte and status read */
+    { "INTENAR",  0xdff01C, 1, 0 }, /* Interrupt enable bits read */
+    { "INTREQR",  0xdff01E, 1, 0 }, /* Interrupt request bits read */
+    { "DSKPTH",   0xdff020, 2, 1 }, /* Disk pointer (high 5 bits) */
+    { "DSKPTL",   0xdff022, 2, 2 }, /* Disk pointer (low 15 bits) */
+    { "DSKLEN",   0xdff024, 2, 0 }, /* Disk lentgh */
 #if 0
+    { "DSKDAT",   0xdff026 }, /* Disk DMA data write */
     { "REFPTR",   0xdff028 }, /* Refresh pointer */
 #endif
-    { "VPOSW",    0xdff02A }, /* Write vert most sig. bits(and frame flop) */
-    { "VHPOSW",   0xdff02C }, /* Write vert and horiz pos of beam */
-    { "COPCON",   0xdff02e }, /* Coprocessor control reg (CDANG) */
-    { "SERDAT",   0xdff030 }, /* Serial port data and stop bits write */
-    { "SERPER",   0xdff032 }, /* Serial port period and control */
-    { "POTGO",    0xdff034 }, /* Pot count start,pot pin drive enable data */
-    { "JOYTEST",  0xdff036 }, /* Write to all 4 joystick-mouse counters at once */
-    { "STREQU",   0xdff038 }, /* Strobe for horiz sync with VB and EQU */
-    { "STRVBL",   0xdff03A }, /* Strobe for horiz sync with VB (vert blank) */
-    { "STRHOR",   0xdff03C }, /* Strobe for horiz sync */
-    { "STRLONG",  0xdff03E }, /* Strobe for identification of long horiz line */
-    { "BLTCON0",  0xdff040 }, /* Blitter control reg 0 */
-    { "BLTCON1",  0xdff042 }, /* Blitter control reg 1 */
-    { "BLTAFWM",  0xdff044 }, /* Blitter first word mask for source A */
-    { "BLTALWM",  0xdff046 }, /* Blitter last word mask for source A */
-    { "BLTCPTH",  0xdff048 }, /* Blitter pointer to source C (high 5 bits) */
-    { "BLTCPTL",  0xdff04A }, /* Blitter pointer to source C (low 15 bits) */
-    { "BLTBPTH",  0xdff04C }, /* Blitter pointer to source B (high 5 bits) */
-    { "BLTBPTL",  0xdff04E }, /* Blitter pointer to source B (low 15 bits) */
-    { "BLTAPTH",  0xdff050 }, /* Blitter pointer to source A (high 5 bits) */
-    { "BLTAPTL",  0xdff052 }, /* Blitter pointer to source A (low 15 bits) */
-    { "BPTDPTH",  0xdff054 }, /* Blitter pointer to destn  D (high 5 bits) */
-    { "BLTDPTL",  0xdff056 }, /* Blitter pointer to destn  D (low 15 bits) */
-    { "BLTSIZE",  0xdff058 }, /* Blitter start and size (win/width,height) */
-    { "BLTCON0L", 0xdff05A }, /* Blitter control 0 lower 8 bits (minterms) */
-    { "BLTSIZV",  0xdff05C }, /* Blitter V size (for 15 bit vert size) */
-    { "BLTSIZH",  0xdff05E }, /* Blitter H size & start (for 11 bit H size) */
-    { "BLTCMOD",  0xdff060 }, /* Blitter modulo for source C */
-    { "BLTBMOD",  0xdff062 }, /* Blitter modulo for source B */
-    { "BLTAMOD",  0xdff064 }, /* Blitter modulo for source A */
-    { "BLTDMOD",  0xdff066 }, /* Blitter modulo for destn  D */
+    { "VPOSW",    0xdff02A, 2, 0 }, /* Write vert most sig. bits(and frame flop) */
+    { "VHPOSW",   0xdff02C, 2, 0 }, /* Write vert and horiz pos of beam */
+    { "COPCON",   0xdff02e, 2, 0 }, /* Coprocessor control reg (CDANG) */
+    { "SERDAT",   0xdff030, 2, 0 }, /* Serial port data and stop bits write */
+    { "SERPER",   0xdff032, 2, 0 }, /* Serial port period and control */
+    { "POTGO",    0xdff034, 2, 0 }, /* Pot count start,pot pin drive enable data */
+    { "JOYTEST",  0xdff036, 2, 0 }, /* Write to all 4 joystick-mouse counters at once */
+    { "STREQU",   0xdff038, 2, 0 }, /* Strobe for horiz sync with VB and EQU */
+    { "STRVBL",   0xdff03A, 2, 0 }, /* Strobe for horiz sync with VB (vert blank) */
+    { "STRHOR",   0xdff03C, 2, 0 }, /* Strobe for horiz sync */
+    { "STRLONG",  0xdff03E, 2, 0 }, /* Strobe for identification of long horiz line */
+    { "BLTCON0",  0xdff040, 2, 0 }, /* Blitter control reg 0 */
+    { "BLTCON1",  0xdff042, 2, 0 }, /* Blitter control reg 1 */
+    { "BLTAFWM",  0xdff044, 2, 0 }, /* Blitter first word mask for source A */
+    { "BLTALWM",  0xdff046, 2, 0 }, /* Blitter last word mask for source A */
+    { "BLTCPTH",  0xdff048, 2, 1 }, /* Blitter pointer to source C (high 5 bits) */
+    { "BLTCPTL",  0xdff04A, 2, 2 }, /* Blitter pointer to source C (low 15 bits) */
+    { "BLTBPTH",  0xdff04C, 2, 1 }, /* Blitter pointer to source B (high 5 bits) */
+    { "BLTBPTL",  0xdff04E, 2, 2 }, /* Blitter pointer to source B (low 15 bits) */
+    { "BLTAPTH",  0xdff050, 2, 1 }, /* Blitter pointer to source A (high 5 bits) */
+    { "BLTAPTL",  0xdff052, 2, 2 }, /* Blitter pointer to source A (low 15 bits) */
+    { "BPTDPTH",  0xdff054, 2, 1 }, /* Blitter pointer to destn  D (high 5 bits) */
+    { "BLTDPTL",  0xdff056, 2, 2 }, /* Blitter pointer to destn  D (low 15 bits) */
+    { "BLTSIZE",  0xdff058, 2, 0 }, /* Blitter start and size (win/width,height) */
+    { "BLTCON0L", 0xdff05A, 2, 0 }, /* Blitter control 0 lower 8 bits (minterms) */
+    { "BLTSIZV",  0xdff05C, 2, 0 }, /* Blitter V size (for 15 bit vert size) */
+    { "BLTSIZH",  0xdff05E, 2, 0 }, /* Blitter H size & start (for 11 bit H size) */
+    { "BLTCMOD",  0xdff060, 2, 0 }, /* Blitter modulo for source C */
+    { "BLTBMOD",  0xdff062, 2, 0 }, /* Blitter modulo for source B */
+    { "BLTAMOD",  0xdff064, 2, 0 }, /* Blitter modulo for source A */
+    { "BLTDMOD",  0xdff066, 2, 0 }, /* Blitter modulo for destn  D */
 #if 0
     { "Unknown",  0xdff068 }, /* Unknown or Unused */
     { "Unknown",  0xdff06a }, /* Unknown or Unused */
     { "Unknown",  0xdff06c }, /* Unknown or Unused */
     { "Unknown",  0xdff06e }, /* Unknown or Unused */
 #endif
-    { "BLTCDAT",  0xdff070 }, /* Blitter source C data reg */
-    { "BLTBDAT",  0xdff072 }, /* Blitter source B data reg */
-    { "BLTADAT",  0xdff074 }, /* Blitter source A data reg */
-    { "BLTDDAT",  0xdff076 }, /* Blitter destination reg */
+    { "BLTCDAT",  0xdff070, 2, 0 }, /* Blitter source C data reg */
+    { "BLTBDAT",  0xdff072, 2, 0 }, /* Blitter source B data reg */
+    { "BLTADAT",  0xdff074, 2, 0 }, /* Blitter source A data reg */
+    { "BLTDDAT",  0xdff076, 2, 0 }, /* Blitter destination reg */
 #if 0
     { "SPRHDAT",  0xdff078 }, /* Ext logic UHRES sprite pointer and data identifier */
     { "BPLHDAT",  0xdff07A }, /* Ext logic UHRES bit plane identifier */
 #endif
-    { "LISAID",   0xdff07C }, /* Chip revision level for Denise/Lisa */
-    { "DSKSYNC",  0xdff07E }, /* Disk sync pattern reg for disk read */
-    { "COP1LCH",  0xdff080 }, /* Coprocessor first location reg (high 5 bits) */
-    { "COP1LCL",  0xdff082 }, /* Coprocessor first location reg (low 15 bits) */
-    { "COP2LCH",  0xdff084 }, /* Coprocessor second reg (high 5 bits) */
-    { "COP2LCL",  0xdff086 }, /* Coprocessor second reg (low 15 bits) */
-    { "COPJMP1",  0xdff088 }, /* Coprocessor restart at first location */
-    { "COPJMP2",  0xdff08A }, /* Coprocessor restart at second location */
+    { "LISAID",   0xdff07C, 1, 0 }, /* Chip revision level for Denise/Lisa */
+    { "DSKSYNC",  0xdff07E, 2, 0 }, /* Disk sync pattern reg for disk read */
+    { "COP1LCH",  0xdff080, 2, 1 }, /* Coprocessor first location reg (high 5 bits) */
+    { "COP1LCL",  0xdff082, 2, 2 }, /* Coprocessor first location reg (low 15 bits) */
+    { "COP2LCH",  0xdff084, 2, 1 }, /* Coprocessor second reg (high 5 bits) */
+    { "COP2LCL",  0xdff086, 2, 2 }, /* Coprocessor second reg (low 15 bits) */
+    { "COPJMP1",  0xdff088, 2, 0 }, /* Coprocessor restart at first location */
+    { "COPJMP2",  0xdff08A, 2, 0 }, /* Coprocessor restart at second location */
 #if 0
     { "COPINS",   0xdff08C }, /* Coprocessor inst fetch identify */
 #endif
-    { "DIWSTRT",  0xdff08E }, /* Display window start (upper left vert-hor pos) */
-    { "DIWSTOP",  0xdff090 }, /* Display window stop (lower right vert-hor pos) */
-    { "DDFSTRT",  0xdff092 }, /* Display bit plane data fetch start.hor pos */
-    { "DDFSTOP",  0xdff094 }, /* Display bit plane data fetch stop.hor pos */
-    { "DMACON",   0xdff096 }, /* DMA control write (clear or set) */
-    { "CLXCON",   0xdff098 }, /* Collision control */
-    { "INTENA",   0xdff09A }, /* Interrupt enable bits (clear or set bits) */
-    { "INTREQ",   0xdff09C }, /* Interrupt request bits (clear or set bits) */
-    { "ADKCON",   0xdff09E }, /* Audio,disk,UART,control */
-    { "AUD0LCH",  0xdff0A0 }, /* Audio channel 0 location (high 5 bits) */
-    { "AUD0LCL",  0xdff0A2 }, /* Audio channel 0 location (low 15 bits) */
-    { "AUD0LEN",  0xdff0A4 }, /* Audio channel 0 lentgh */
-    { "AUD0PER",  0xdff0A6 }, /* Audio channel 0 period */
-    { "AUD0VOL",  0xdff0A8 }, /* Audio channel 0 volume */
-    { "AUD0DAT",  0xdff0AA }, /* Audio channel 0 data */
+    { "DIWSTRT",  0xdff08E, 2, 0 }, /* Display window start (upper left vert-hor pos) */
+    { "DIWSTOP",  0xdff090, 2, 0 }, /* Display window stop (lower right vert-hor pos) */
+    { "DDFSTRT",  0xdff092, 2, 0 }, /* Display bit plane data fetch start.hor pos */
+    { "DDFSTOP",  0xdff094, 2, 0 }, /* Display bit plane data fetch stop.hor pos */
+    { "DMACON",   0xdff096, 2, 0 }, /* DMA control write (clear or set) */
+    { "CLXCON",   0xdff098, 2, 0 }, /* Collision control */
+    { "INTENA",   0xdff09A, 2, 0 }, /* Interrupt enable bits (clear or set bits) */
+    { "INTREQ",   0xdff09C, 2, 0 }, /* Interrupt request bits (clear or set bits) */
+    { "ADKCON",   0xdff09E, 2, 0 }, /* Audio,disk,UART,control */
+    { "AUD0LCH",  0xdff0A0, 2, 1 }, /* Audio channel 0 location (high 5 bits) */
+    { "AUD0LCL",  0xdff0A2, 2, 2 }, /* Audio channel 0 location (low 15 bits) */
+    { "AUD0LEN",  0xdff0A4, 2, 0 }, /* Audio channel 0 lentgh */
+    { "AUD0PER",  0xdff0A6, 2, 0 }, /* Audio channel 0 period */
+    { "AUD0VOL",  0xdff0A8, 2, 0 }, /* Audio channel 0 volume */
+    { "AUD0DAT",  0xdff0AA, 2, 0 }, /* Audio channel 0 data */
 #if 0
     { "Unknown",  0xdff0AC }, /* Unknown or Unused */
     { "Unknown",  0xdff0AE }, /* Unknown or Unused */
 #endif
-    { "AUD1LCH",  0xdff0B0 }, /* Audio channel 1 location (high 5 bits) */
-    { "AUD1LCL",  0xdff0B2 }, /* Audio channel 1 location (low 15 bits) */
-    { "AUD1LEN",  0xdff0B4 }, /* Audio channel 1 lentgh */
-    { "AUD1PER",  0xdff0B6 }, /* Audio channel 1 period */
-    { "AUD1VOL",  0xdff0B8 }, /* Audio channel 1 volume */
-    { "AUD1DAT",  0xdff0BA }, /* Audio channel 1 data */
+    { "AUD1LCH",  0xdff0B0, 2, 0 }, /* Audio channel 1 location (high 5 bits) */
+    { "AUD1LCL",  0xdff0B2, 2, 0 }, /* Audio channel 1 location (low 15 bits) */
+    { "AUD1LEN",  0xdff0B4, 2, 0 }, /* Audio channel 1 lentgh */
+    { "AUD1PER",  0xdff0B6, 2, 0 }, /* Audio channel 1 period */
+    { "AUD1VOL",  0xdff0B8, 2, 0 }, /* Audio channel 1 volume */
+    { "AUD1DAT",  0xdff0BA, 2, 0 }, /* Audio channel 1 data */
 #if 0
     { "Unknown",  0xdff0BC }, /* Unknown or Unused */
     { "Unknown",  0xdff0BE }, /* Unknown or Unused */
 #endif
-    { "AUD2LCH",  0xdff0C0 }, /* Audio channel 2 location (high 5 bits) */
-    { "AUD2LCL",  0xdff0C2 }, /* Audio channel 2 location (low 15 bits) */
-    { "AUD2LEN",  0xdff0C4 }, /* Audio channel 2 lentgh */
-    { "AUD2PER",  0xdff0C6 }, /* Audio channel 2 period */
-    { "AUD2VOL",  0xdff0C8 }, /* Audio channel 2 volume */
-    { "AUD2DAT",  0xdff0CA }, /* Audio channel 2 data */
+    { "AUD2LCH",  0xdff0C0, 2, 0 }, /* Audio channel 2 location (high 5 bits) */
+    { "AUD2LCL",  0xdff0C2, 2, 0 }, /* Audio channel 2 location (low 15 bits) */
+    { "AUD2LEN",  0xdff0C4, 2, 0 }, /* Audio channel 2 lentgh */
+    { "AUD2PER",  0xdff0C6, 2, 0 }, /* Audio channel 2 period */
+    { "AUD2VOL",  0xdff0C8, 2, 0 }, /* Audio channel 2 volume */
+    { "AUD2DAT",  0xdff0CA, 2, 0 }, /* Audio channel 2 data */
 #if 0
     { "Unknown",  0xdff0CC }, /* Unknown or Unused */
     { "Unknown",  0xdff0CE }, /* Unknown or Unused */
 #endif
-    { "AUD3LCH",  0xdff0D0 }, /* Audio channel 3 location (high 5 bits) */
-    { "AUD3LCL",  0xdff0D2 }, /* Audio channel 3 location (low 15 bits) */
-    { "AUD3LEN",  0xdff0D4 }, /* Audio channel 3 lentgh */
-    { "AUD3PER",  0xdff0D6 }, /* Audio channel 3 period */
-    { "AUD3VOL",  0xdff0D8 }, /* Audio channel 3 volume */
-    { "AUD3DAT",  0xdff0DA }, /* Audio channel 3 data */
+    { "AUD3LCH",  0xdff0D0, 2, 0 }, /* Audio channel 3 location (high 5 bits) */
+    { "AUD3LCL",  0xdff0D2, 2, 0 }, /* Audio channel 3 location (low 15 bits) */
+    { "AUD3LEN",  0xdff0D4, 2, 0 }, /* Audio channel 3 lentgh */
+    { "AUD3PER",  0xdff0D6, 2, 0 }, /* Audio channel 3 period */
+    { "AUD3VOL",  0xdff0D8, 2, 0 }, /* Audio channel 3 volume */
+    { "AUD3DAT",  0xdff0DA, 2, 0 }, /* Audio channel 3 data */
 #if 0
     { "Unknown",  0xdff0DC }, /* Unknown or Unused */
     { "Unknown",  0xdff0DE }, /* Unknown or Unused */
 #endif
-    { "BPL1PTH",  0xdff0E0 }, /* Bit plane pointer 1 (high 5 bits) */
-    { "BPL1PTL",  0xdff0E2 }, /* Bit plane pointer 1 (low 15 bits) */
-    { "BPL2PTH",  0xdff0E4 }, /* Bit plane pointer 2 (high 5 bits) */
-    { "BPL2PTL",  0xdff0E6 }, /* Bit plane pointer 2 (low 15 bits) */
-    { "BPL3PTH",  0xdff0E8 }, /* Bit plane pointer 3 (high 5 bits) */
-    { "BPL3PTL",  0xdff0EA }, /* Bit plane pointer 3 (low 15 bits) */
-    { "BPL4PTH",  0xdff0EC }, /* Bit plane pointer 4 (high 5 bits) */
-    { "BPL4PTL",  0xdff0EE }, /* Bit plane pointer 4 (low 15 bits) */
-    { "BPL5PTH",  0xdff0F0 }, /* Bit plane pointer 5 (high 5 bits) */
-    { "BPL5PTL",  0xdff0F2 }, /* Bit plane pointer 5 (low 15 bits) */
-    { "BPL6PTH",  0xdff0F4 }, /* Bit plane pointer 6 (high 5 bits) */
-    { "BPL6PTL",  0xdff0F6 }, /* Bit plane pointer 6 (low 15 bits) */
-    { "BPL7PTH",  0xdff0F8 }, /* Bit plane pointer 7 (high 5 bits) */
-    { "BPL7PTL",  0xdff0FA }, /* Bit plane pointer 7 (low 15 bits) */
-    { "BPL8PTH",  0xdff0FC }, /* Bit plane pointer 8 (high 5 bits) */
-    { "BPL8PTL",  0xdff0FE }, /* Bit plane pointer 8 (low 15 bits) */
-    { "BPLCON0",  0xdff100 }, /* Bit plane control reg (misc control bits) */
-    { "BPLCON1",  0xdff102 }, /* Bit plane control reg (scroll val PF1,PF2) */
-    { "BPLCON2",  0xdff104 }, /* Bit plane control reg (priority control) */
-    { "BPLCON3",  0xdff106 }, /* Bit plane control reg (enhanced features) */
-    { "BPL1MOD",  0xdff108 }, /* Bit plane modulo (odd planes,or active- fetch lines if bitplane scan-doubling is enabled */
-    { "BPL2MOD",  0xdff10A }, /* Bit plane modulo (even planes or inactive- fetch lines if bitplane scan-doubling is enabled */
-    { "BPLCON4",  0xdff10C }, /* Bit plane control reg (bitplane and sprite masks) */
-    { "CLXCON2",  0xdff10e }, /* Extended collision control reg */
-    { "BPL1DAT",  0xdff110 }, /* Bit plane 1 data (parallel to serial con- vert) */
-    { "BPL2DAT",  0xdff112 }, /* Bit plane 2 data (parallel to serial con- vert) */
-    { "BPL3DAT",  0xdff114 }, /* Bit plane 3 data (parallel to serial con- vert) */
-    { "BPL4DAT",  0xdff116 }, /* Bit plane 4 data (parallel to serial con- vert) */
-    { "BPL5DAT",  0xdff118 }, /* Bit plane 5 data (parallel to serial con- vert) */
-    { "BPL6DAT",  0xdff11a }, /* Bit plane 6 data (parallel to serial con- vert) */
-    { "BPL7DAT",  0xdff11c }, /* Bit plane 7 data (parallel to serial con- vert) */
-    { "BPL8DAT",  0xdff11e }, /* Bit plane 8 data (parallel to serial con- vert) */
-    { "SPR0PTH",  0xdff120 }, /* Sprite 0 pointer (high 5 bits) */
-    { "SPR0PTL",  0xdff122 }, /* Sprite 0 pointer (low 15 bits) */
-    { "SPR1PTH",  0xdff124 }, /* Sprite 1 pointer (high 5 bits) */
-    { "SPR1PTL",  0xdff126 }, /* Sprite 1 pointer (low 15 bits) */
-    { "SPR2PTH",  0xdff128 }, /* Sprite 2 pointer (high 5 bits) */
-    { "SPR2PTL",  0xdff12A }, /* Sprite 2 pointer (low 15 bits) */
-    { "SPR3PTH",  0xdff12C }, /* Sprite 3 pointer (high 5 bits) */
-    { "SPR3PTL",  0xdff12E }, /* Sprite 3 pointer (low 15 bits) */
-    { "SPR4PTH",  0xdff130 }, /* Sprite 4 pointer (high 5 bits) */
-    { "SPR4PTL",  0xdff132 }, /* Sprite 4 pointer (low 15 bits) */
-    { "SPR5PTH",  0xdff134 }, /* Sprite 5 pointer (high 5 bits) */
-    { "SPR5PTL",  0xdff136 }, /* Sprite 5 pointer (low 15 bits) */
-    { "SPR6PTH",  0xdff138 }, /* Sprite 6 pointer (high 5 bits) */
-    { "SPR6PTL",  0xdff13A }, /* Sprite 6 pointer (low 15 bits) */
-    { "SPR7PTH",  0xdff13C }, /* Sprite 7 pointer (high 5 bits) */
-    { "SPR7PTL",  0xdff13E }, /* Sprite 7 pointer (low 15 bits) */
-    { "SPR0POS",  0xdff140 }, /* Sprite 0 vert-horiz start pos data */
-    { "SPR0CTL",  0xdff142 }, /* Sprite 0 position and control data */
-    { "SPR0DATA", 0xdff144 }, /* Sprite 0 image data register A */
-    { "SPR0DATB", 0xdff146 }, /* Sprite 0 image data register B */
-    { "SPR1POS",  0xdff148 }, /* Sprite 1 vert-horiz start pos data */
-    { "SPR1CTL",  0xdff14A }, /* Sprite 1 position and control data */
-    { "SPR1DATA", 0xdff14C }, /* Sprite 1 image data register A */
-    { "SPR1DATB", 0xdff14E }, /* Sprite 1 image data register B */
-    { "SPR2POS",  0xdff150 }, /* Sprite 2 vert-horiz start pos data */
-    { "SPR2CTL",  0xdff152 }, /* Sprite 2 position and control data */
-    { "SPR2DATA", 0xdff154 }, /* Sprite 2 image data register A */
-    { "SPR2DATB", 0xdff156 }, /* Sprite 2 image data register B */
-    { "SPR3POS",  0xdff158 }, /* Sprite 3 vert-horiz start pos data */
-    { "SPR3CTL",  0xdff15A }, /* Sprite 3 position and control data */
-    { "SPR3DATA", 0xdff15C }, /* Sprite 3 image data register A */
-    { "SPR3DATB", 0xdff15E }, /* Sprite 3 image data register B */
-    { "SPR4POS",  0xdff160 }, /* Sprite 4 vert-horiz start pos data */
-    { "SPR4CTL",  0xdff162 }, /* Sprite 4 position and control data */
-    { "SPR4DATA", 0xdff164 }, /* Sprite 4 image data register A */
-    { "SPR4DATB", 0xdff166 }, /* Sprite 4 image data register B */
-    { "SPR5POS",  0xdff168 }, /* Sprite 5 vert-horiz start pos data */
-    { "SPR5CTL",  0xdff16A }, /* Sprite 5 position and control data */
-    { "SPR5DATA", 0xdff16C }, /* Sprite 5 image data register A */
-    { "SPR5DATB", 0xdff16E }, /* Sprite 5 image data register B */
-    { "SPR6POS",  0xdff170 }, /* Sprite 6 vert-horiz start pos data */
-    { "SPR6CTL",  0xdff172 }, /* Sprite 6 position and control data */
-    { "SPR6DATA", 0xdff174 }, /* Sprite 6 image data register A */
-    { "SPR6DATB", 0xdff176 }, /* Sprite 6 image data register B */
-    { "SPR7POS",  0xdff178 }, /* Sprite 7 vert-horiz start pos data */
-    { "SPR7CTL",  0xdff17A }, /* Sprite 7 position and control data */
-    { "SPR7DATA", 0xdff17C }, /* Sprite 7 image data register A */
-    { "SPR7DATB", 0xdff17E }, /* Sprite 7 image data register B */
-    { "COLOR00",  0xdff180 }, /* Color table 00 */
-    { "COLOR01",  0xdff182 }, /* Color table 01 */
-    { "COLOR02",  0xdff184 }, /* Color table 02 */
-    { "COLOR03",  0xdff186 }, /* Color table 03 */
-    { "COLOR04",  0xdff188 }, /* Color table 04 */
-    { "COLOR05",  0xdff18A }, /* Color table 05 */
-    { "COLOR06",  0xdff18C }, /* Color table 06 */
-    { "COLOR07",  0xdff18E }, /* Color table 07 */
-    { "COLOR08",  0xdff190 }, /* Color table 08 */
-    { "COLOR09",  0xdff192 }, /* Color table 09 */
-    { "COLOR10",  0xdff194 }, /* Color table 10 */
-    { "COLOR11",  0xdff196 }, /* Color table 11 */
-    { "COLOR12",  0xdff198 }, /* Color table 12 */
-    { "COLOR13",  0xdff19A }, /* Color table 13 */
-    { "COLOR14",  0xdff19C }, /* Color table 14 */
-    { "COLOR15",  0xdff19E }, /* Color table 15 */
-    { "COLOR16",  0xdff1A0 }, /* Color table 16 */
-    { "COLOR17",  0xdff1A2 }, /* Color table 17 */
-    { "COLOR18",  0xdff1A4 }, /* Color table 18 */
-    { "COLOR19",  0xdff1A6 }, /* Color table 19 */
-    { "COLOR20",  0xdff1A8 }, /* Color table 20 */
-    { "COLOR21",  0xdff1AA }, /* Color table 21 */
-    { "COLOR22",  0xdff1AC }, /* Color table 22 */
-    { "COLOR23",  0xdff1AE }, /* Color table 23 */
-    { "COLOR24",  0xdff1B0 }, /* Color table 24 */
-    { "COLOR25",  0xdff1B2 }, /* Color table 25 */
-    { "COLOR26",  0xdff1B4 }, /* Color table 26 */
-    { "COLOR27",  0xdff1B6 }, /* Color table 27 */
-    { "COLOR28",  0xdff1B8 }, /* Color table 28 */
-    { "COLOR29",  0xdff1BA }, /* Color table 29 */
-    { "COLOR30",  0xdff1BC }, /* Color table 30 */
-    { "COLOR31",  0xdff1BE }, /* Color table 31 */
-    { "HTOTAL",   0xdff1C0 }, /* Highest number count in horiz line (VARBEAMEN = 1) */
-    { "HSSTOP",   0xdff1C2 }, /* Horiz line pos for HSYNC stop */
-    { "HBSTRT",   0xdff1C4 }, /* Horiz line pos for HBLANK start */
-    { "HBSTOP",   0xdff1C6 }, /* Horiz line pos for HBLANK stop */
-    { "VTOTAL",   0xdff1C8 }, /* Highest numbered vertical line (VARBEAMEN = 1) */
-    { "VSSTOP",   0xdff1CA }, /* Vert line for VBLANK start */
-    { "VBSTRT",   0xdff1CC }, /* Vert line for VBLANK start */
-    { "VBSTOP",   0xdff1CE }, /* Vert line for VBLANK stop */
+    { "BPL1PTH",  0xdff0E0, 2 }, /* Bit plane pointer 1 (high 5 bits) */
+    { "BPL1PTL",  0xdff0E2, 2 }, /* Bit plane pointer 1 (low 15 bits) */
+    { "BPL2PTH",  0xdff0E4, 2 }, /* Bit plane pointer 2 (high 5 bits) */
+    { "BPL2PTL",  0xdff0E6, 2 }, /* Bit plane pointer 2 (low 15 bits) */
+    { "BPL3PTH",  0xdff0E8, 2 }, /* Bit plane pointer 3 (high 5 bits) */
+    { "BPL3PTL",  0xdff0EA, 2 }, /* Bit plane pointer 3 (low 15 bits) */
+    { "BPL4PTH",  0xdff0EC, 2 }, /* Bit plane pointer 4 (high 5 bits) */
+    { "BPL4PTL",  0xdff0EE, 2 }, /* Bit plane pointer 4 (low 15 bits) */
+    { "BPL5PTH",  0xdff0F0, 2 }, /* Bit plane pointer 5 (high 5 bits) */
+    { "BPL5PTL",  0xdff0F2, 2 }, /* Bit plane pointer 5 (low 15 bits) */
+    { "BPL6PTH",  0xdff0F4, 2 }, /* Bit plane pointer 6 (high 5 bits) */
+    { "BPL6PTL",  0xdff0F6, 2 }, /* Bit plane pointer 6 (low 15 bits) */
+    { "BPL7PTH",  0xdff0F8, 2 }, /* Bit plane pointer 7 (high 5 bits) */
+    { "BPL7PTL",  0xdff0FA, 2 }, /* Bit plane pointer 7 (low 15 bits) */
+    { "BPL8PTH",  0xdff0FC, 2 }, /* Bit plane pointer 8 (high 5 bits) */
+    { "BPL8PTL",  0xdff0FE, 2 }, /* Bit plane pointer 8 (low 15 bits) */
+    { "BPLCON0",  0xdff100, 2 }, /* Bit plane control reg (misc control bits) */
+    { "BPLCON1",  0xdff102, 2 }, /* Bit plane control reg (scroll val PF1,PF2) */
+    { "BPLCON2",  0xdff104, 2 }, /* Bit plane control reg (priority control) */
+    { "BPLCON3",  0xdff106, 2 }, /* Bit plane control reg (enhanced features) */
+    { "BPL1MOD",  0xdff108, 2 }, /* Bit plane modulo (odd planes,or active- fetch lines if bitplane scan-doubling is enabled */
+    { "BPL2MOD",  0xdff10A, 2 }, /* Bit plane modulo (even planes or inactive- fetch lines if bitplane scan-doubling is enabled */
+    { "BPLCON4",  0xdff10C, 2 }, /* Bit plane control reg (bitplane and sprite masks) */
+    { "CLXCON2",  0xdff10e, 2 }, /* Extended collision control reg */
+    { "BPL1DAT",  0xdff110, 2 }, /* Bit plane 1 data (parallel to serial con- vert) */
+    { "BPL2DAT",  0xdff112, 2 }, /* Bit plane 2 data (parallel to serial con- vert) */
+    { "BPL3DAT",  0xdff114, 2 }, /* Bit plane 3 data (parallel to serial con- vert) */
+    { "BPL4DAT",  0xdff116, 2 }, /* Bit plane 4 data (parallel to serial con- vert) */
+    { "BPL5DAT",  0xdff118, 2 }, /* Bit plane 5 data (parallel to serial con- vert) */
+    { "BPL6DAT",  0xdff11a, 2 }, /* Bit plane 6 data (parallel to serial con- vert) */
+    { "BPL7DAT",  0xdff11c, 2 }, /* Bit plane 7 data (parallel to serial con- vert) */
+    { "BPL8DAT",  0xdff11e, 2 }, /* Bit plane 8 data (parallel to serial con- vert) */
+    { "SPR0PTH",  0xdff120, 2 }, /* Sprite 0 pointer (high 5 bits) */
+    { "SPR0PTL",  0xdff122, 2 }, /* Sprite 0 pointer (low 15 bits) */
+    { "SPR1PTH",  0xdff124, 2 }, /* Sprite 1 pointer (high 5 bits) */
+    { "SPR1PTL",  0xdff126, 2 }, /* Sprite 1 pointer (low 15 bits) */
+    { "SPR2PTH",  0xdff128, 2 }, /* Sprite 2 pointer (high 5 bits) */
+    { "SPR2PTL",  0xdff12A, 2 }, /* Sprite 2 pointer (low 15 bits) */
+    { "SPR3PTH",  0xdff12C, 2 }, /* Sprite 3 pointer (high 5 bits) */
+    { "SPR3PTL",  0xdff12E, 2 }, /* Sprite 3 pointer (low 15 bits) */
+    { "SPR4PTH",  0xdff130, 2 }, /* Sprite 4 pointer (high 5 bits) */
+    { "SPR4PTL",  0xdff132, 2 }, /* Sprite 4 pointer (low 15 bits) */
+    { "SPR5PTH",  0xdff134, 2 }, /* Sprite 5 pointer (high 5 bits) */
+    { "SPR5PTL",  0xdff136, 2 }, /* Sprite 5 pointer (low 15 bits) */
+    { "SPR6PTH",  0xdff138, 2 }, /* Sprite 6 pointer (high 5 bits) */
+    { "SPR6PTL",  0xdff13A, 2 }, /* Sprite 6 pointer (low 15 bits) */
+    { "SPR7PTH",  0xdff13C, 2 }, /* Sprite 7 pointer (high 5 bits) */
+    { "SPR7PTL",  0xdff13E, 2 }, /* Sprite 7 pointer (low 15 bits) */
+    { "SPR0POS",  0xdff140, 2 }, /* Sprite 0 vert-horiz start pos data */
+    { "SPR0CTL",  0xdff142, 2 }, /* Sprite 0 position and control data */
+    { "SPR0DATA", 0xdff144, 2 }, /* Sprite 0 image data register A */
+    { "SPR0DATB", 0xdff146, 2 }, /* Sprite 0 image data register B */
+    { "SPR1POS",  0xdff148, 2 }, /* Sprite 1 vert-horiz start pos data */
+    { "SPR1CTL",  0xdff14A, 2 }, /* Sprite 1 position and control data */
+    { "SPR1DATA", 0xdff14C, 2 }, /* Sprite 1 image data register A */
+    { "SPR1DATB", 0xdff14E, 2 }, /* Sprite 1 image data register B */
+    { "SPR2POS",  0xdff150, 2 }, /* Sprite 2 vert-horiz start pos data */
+    { "SPR2CTL",  0xdff152, 2 }, /* Sprite 2 position and control data */
+    { "SPR2DATA", 0xdff154, 2 }, /* Sprite 2 image data register A */
+    { "SPR2DATB", 0xdff156, 2 }, /* Sprite 2 image data register B */
+    { "SPR3POS",  0xdff158, 2 }, /* Sprite 3 vert-horiz start pos data */
+    { "SPR3CTL",  0xdff15A, 2 }, /* Sprite 3 position and control data */
+    { "SPR3DATA", 0xdff15C, 2 }, /* Sprite 3 image data register A */
+    { "SPR3DATB", 0xdff15E, 2 }, /* Sprite 3 image data register B */
+    { "SPR4POS",  0xdff160, 2 }, /* Sprite 4 vert-horiz start pos data */
+    { "SPR4CTL",  0xdff162, 2 }, /* Sprite 4 position and control data */
+    { "SPR4DATA", 0xdff164, 2 }, /* Sprite 4 image data register A */
+    { "SPR4DATB", 0xdff166, 2 }, /* Sprite 4 image data register B */
+    { "SPR5POS",  0xdff168, 2 }, /* Sprite 5 vert-horiz start pos data */
+    { "SPR5CTL",  0xdff16A, 2 }, /* Sprite 5 position and control data */
+    { "SPR5DATA", 0xdff16C, 2 }, /* Sprite 5 image data register A */
+    { "SPR5DATB", 0xdff16E, 2 }, /* Sprite 5 image data register B */
+    { "SPR6POS",  0xdff170, 2 }, /* Sprite 6 vert-horiz start pos data */
+    { "SPR6CTL",  0xdff172, 2 }, /* Sprite 6 position and control data */
+    { "SPR6DATA", 0xdff174, 2 }, /* Sprite 6 image data register A */
+    { "SPR6DATB", 0xdff176, 2 }, /* Sprite 6 image data register B */
+    { "SPR7POS",  0xdff178, 2 }, /* Sprite 7 vert-horiz start pos data */
+    { "SPR7CTL",  0xdff17A, 2 }, /* Sprite 7 position and control data */
+    { "SPR7DATA", 0xdff17C, 2 }, /* Sprite 7 image data register A */
+    { "SPR7DATB", 0xdff17E, 2 }, /* Sprite 7 image data register B */
+    { "COLOR00",  0xdff180, 2 }, /* Color table 00 */
+    { "COLOR01",  0xdff182, 2 }, /* Color table 01 */
+    { "COLOR02",  0xdff184, 2 }, /* Color table 02 */
+    { "COLOR03",  0xdff186, 2 }, /* Color table 03 */
+    { "COLOR04",  0xdff188, 2 }, /* Color table 04 */
+    { "COLOR05",  0xdff18A, 2 }, /* Color table 05 */
+    { "COLOR06",  0xdff18C, 2 }, /* Color table 06 */
+    { "COLOR07",  0xdff18E, 2 }, /* Color table 07 */
+    { "COLOR08",  0xdff190, 2 }, /* Color table 08 */
+    { "COLOR09",  0xdff192, 2 }, /* Color table 09 */
+    { "COLOR10",  0xdff194, 2 }, /* Color table 10 */
+    { "COLOR11",  0xdff196, 2 }, /* Color table 11 */
+    { "COLOR12",  0xdff198, 2 }, /* Color table 12 */
+    { "COLOR13",  0xdff19A, 2 }, /* Color table 13 */
+    { "COLOR14",  0xdff19C, 2 }, /* Color table 14 */
+    { "COLOR15",  0xdff19E, 2 }, /* Color table 15 */
+    { "COLOR16",  0xdff1A0, 2 }, /* Color table 16 */
+    { "COLOR17",  0xdff1A2, 2 }, /* Color table 17 */
+    { "COLOR18",  0xdff1A4, 2 }, /* Color table 18 */
+    { "COLOR19",  0xdff1A6, 2 }, /* Color table 19 */
+    { "COLOR20",  0xdff1A8, 2 }, /* Color table 20 */
+    { "COLOR21",  0xdff1AA, 2 }, /* Color table 21 */
+    { "COLOR22",  0xdff1AC, 2 }, /* Color table 22 */
+    { "COLOR23",  0xdff1AE, 2 }, /* Color table 23 */
+    { "COLOR24",  0xdff1B0, 2 }, /* Color table 24 */
+    { "COLOR25",  0xdff1B2, 2 }, /* Color table 25 */
+    { "COLOR26",  0xdff1B4, 2 }, /* Color table 26 */
+    { "COLOR27",  0xdff1B6, 2 }, /* Color table 27 */
+    { "COLOR28",  0xdff1B8, 2 }, /* Color table 28 */
+    { "COLOR29",  0xdff1BA, 2 }, /* Color table 29 */
+    { "COLOR30",  0xdff1BC, 2 }, /* Color table 30 */
+    { "COLOR31",  0xdff1BE, 2 }, /* Color table 31 */
+    { "HTOTAL",   0xdff1C0, 2 }, /* Highest number count in horiz line (VARBEAMEN = 1) */
+    { "HSSTOP",   0xdff1C2, 2 }, /* Horiz line pos for HSYNC stop */
+    { "HBSTRT",   0xdff1C4, 2 }, /* Horiz line pos for HBLANK start */
+    { "HBSTOP",   0xdff1C6, 2 }, /* Horiz line pos for HBLANK stop */
+    { "VTOTAL",   0xdff1C8, 2 }, /* Highest numbered vertical line (VARBEAMEN = 1) */
+    { "VSSTOP",   0xdff1CA, 2 }, /* Vert line for VBLANK start */
+    { "VBSTRT",   0xdff1CC, 2 }, /* Vert line for VBLANK start */
+    { "VBSTOP",   0xdff1CE, 2 }, /* Vert line for VBLANK stop */
 #if 0
     { "SPRHSTRT", 0xdff1D0 }, /* UHRES sprite vertical start */
     { "SPRHSTOP", 0xdff1D2 }, /* UHRES sprite vertical stop */
@@ -376,11 +376,11 @@ struct customData custd[] =
     { "HHPOSW",   0xdff1D8 }, /* DUAL mode hires H beam counter write */
     { "HHPOSR",   0xdff1DA }, /* DUAL mode hires H beam counter read */
 #endif
-    { "BEAMCON0", 0xdff1DC }, /* Beam counter control register (SHRES,UHRES,PAL) */
-    { "HSSTRT",   0xdff1DE }, /* Horizontal sync start (VARHSY) */
-    { "VSSTRT",   0xdff1E0 }, /* Vertical sync start (VARVSY) */
-    { "HCENTER",  0xdff1E2 }, /* Horizontal pos for vsync on interlace */
-    { "DIWHIGH",  0xdff1E4 }, /* Display window upper bits for start/stop */
+    { "BEAMCON0", 0xdff1DC, 2 }, /* Beam counter control register (SHRES,UHRES,PAL) */
+    { "HSSTRT",   0xdff1DE, 2 }, /* Horizontal sync start (VARHSY) */
+    { "VSSTRT",   0xdff1E0, 2 }, /* Vertical sync start (VARVSY) */
+    { "HCENTER",  0xdff1E2, 2 }, /* Horizontal pos for vsync on interlace */
+    { "DIWHIGH",  0xdff1E4, 2 }, /* Display window upper bits for start/stop */
 #if 0
     { "BPLHMOD",  0xdff1E6 }, /* UHRES bit plane modulo */
     { "SPRHPTH",  0xdff1E8 }, /* UHRES sprite pointer (high 5 bits) */
@@ -394,7 +394,7 @@ struct customData custd[] =
     { "RESERVED", 0xdff1F8 }, /* Reserved (forever i guess!) */
     { "RESERVED", 0xdff1Fa }, /* Reserved (forever i guess!) */
 #endif
-    { "FMODE",    0xdff1FC }, /* Fetch mode register */
+    { "FMODE",    0xdff1FC, 2 }, /* Fetch mode register */
 #if 0
     { "NO-OP(NULL)", 0xdff1FE },        /*   Can also indicate last 2 or 3 refresh
                                            cycles or the restart of the COPPER after lockup.*/
index 4da9bb843dd5d4e98c4244be66d66b864955ed0d..01941c528ca7712d38c19520374a05169d810aae 100755 (executable)
@@ -15,6 +15,7 @@ struct customData
 {
     const char *name;
     uae_u32 adr;
+    uae_u8 rw, dmaadr;
 };
 
 
index 889d5326c5c7629dd2a1a55dd8905f04be95c873..95480b8a1b07a54e97d05627c2c3a4a95818fa07 100755 (executable)
--- a/memory.c
+++ b/memory.c
@@ -608,6 +608,7 @@ static void a1000_handle_kickstart (int mode)
     if (mode == 0) {
        a1000_kickstart_mode = 0;
        memcpy (kickmemory, kickmemory + 262144, 262144);
+        kickstart_version = (kickmemory[262144 + 12] << 8) | kickmemory[262144 + 13];
     } else {
        a1000_kickstart_mode = 1;
        memset (kickmemory, 0, 262144);
@@ -615,7 +616,6 @@ static void a1000_handle_kickstart (int mode)
        memcpy (kickmemory + 131072, a1000_bootrom, 65536);
         kickstart_version = 0;
     }
-    kickstart_version = (kickmemory[262144 + 12] << 8) | kickmemory[262144 + 13];
 }
 
 void a1000_reset (void)
@@ -1046,6 +1046,8 @@ static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksu
         a1000_bootrom = malloc (65536);
         memcpy (a1000_bootrom, kickmemory, 65536);
         a1000_handle_kickstart (1);
+       i = 524288;
+       dochecksum = 0;
     }
     if (dochecksum && i >= 262144)
        kickstart_checksum (mem, size);
index 20bcfa2228702e93af3eb2a5137bb899f5a13066..529c20ab222a11d3d8ba7fa86725bab5fff29089 100755 (executable)
@@ -651,10 +651,8 @@ void AVIOutput_Restart(void)
 void AVIOutput_End(void)
 {
        EnterCriticalSection(&AVIOutput_CriticalSection);
-       
-       avioutput_audio = avioutput_video = 0;
+
        avioutput_enabled = 0;
-       
        if(has)
        {
                acmStreamUnprepareHeader(has, &ash, 0);
@@ -720,7 +718,7 @@ void AVIOutput_Begin(void)
        } else {
            ext1 = ".avi"; ext2 = ".wav";
        }
-       if (strlen (avioutput_filename) >= 4 && strcmpi (avioutput_filename + strlen (avioutput_filename) - 4, ext2))
+       if (strlen (avioutput_filename) >= 4 && !strcmpi (avioutput_filename + strlen (avioutput_filename) - 4, ext2))
            avioutput_filename[strlen (avioutput_filename) - 4] = 0;
        if (strlen (avioutput_filename) >= 4 && strcmpi (avioutput_filename + strlen (avioutput_filename) - 4, ext1))
            strcat (avioutput_filename, ext1);
diff --git a/od-win32/drivesound.c b/od-win32/drivesound.c
deleted file mode 100755 (executable)
index 4782c7b..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "sysconfig.h"
-#include "sysdeps.h"
-
-#include "config.h"
-#include "options.h"
-#include "zfile.h"
-#include "sounddep/sound.h"
-#include "dxwrap.h"
-
-#include <windows.h>
-#include <mmsystem.h>
-#include <dsound.h>
-
-static LPDIRECTSOUND lpDS;
-static LPDIRECTSOUNDBUFFER lpDSBprimary;
-
-#define DRIVESOUND_CLICK 0
-#define DRIVESOUND_STARTUP 1
-#define DRIVESOUND_SPIN 2
-#define DRIVESOUND_END 3
-
-static LPDIRECTSOUNDBUFFER samples[4][DRIVESOUND_END];
-static int drivesound_enabled, drive_enabled[4];
-static int click_frequency[4];
-static int minfreq, maxfreq;
-
-extern GUID sound_device_guid[];
-
-static void close_audio_ds (void)
-{
-    int i, j;
-
-    drivesound_enabled = 0;
-    for (i = 0; i < DRIVESOUND_END; i++) {
-       for (j = 0; j < 4; j++) {
-           if (samples[j][i])
-               IDirectSound_Release (samples[j][i]);
-           samples[j][i] = 0;
-           drive_enabled[j] = 0;
-       }
-    }
-    if (lpDSBprimary)
-       IDirectSound_Release (lpDSBprimary);
-    lpDSBprimary = 0;
-    if (lpDS) {
-       IDirectSound_Release (lpDS);
-       write_log ("DRIVESOUND: DirectSound driver freed\n");
-    }
-    lpDS = 0;
-}
-
-extern HWND hMainWnd;
-
-static int createsample (int drivenum, int samplenum, char *path)
-{
-    struct zfile *f;
-    uae_u8 *buf = 0;
-    int size, freq = 44100;
-    WAVEFORMATEX wavfmt;
-    DSBUFFERDESC sound_buffer;
-    HRESULT hr;
-    void *b1, *b2;
-    DWORD s1, s2;
-
-    f = zfile_fopen (path, "rb");
-    if (!f) {
-       write_log ("DRIVESOUND: can't open '%s'\n", path);
-       goto error;
-    }
-    zfile_fseek (f, 0, SEEK_END);
-    size = zfile_ftell (f);
-    buf = malloc (size);
-    zfile_fseek (f, 0, SEEK_SET);
-    zfile_fread (buf, size, 1, f);
-    zfile_fclose (f);
-
-    if (samplenum == DRIVESOUND_CLICK)
-       click_frequency[drivenum] = freq;
-    wavfmt.wFormatTag = WAVE_FORMAT_PCM;
-    wavfmt.nChannels = 2;
-    wavfmt.nSamplesPerSec = freq;
-    wavfmt.wBitsPerSample = 16;
-    wavfmt.nBlockAlign = 16 / 8 * wavfmt.nChannels;
-    wavfmt.nAvgBytesPerSec = wavfmt.nBlockAlign * freq;
-    memset (&sound_buffer, 0, sizeof (sound_buffer));
-    sound_buffer.dwSize = sizeof (sound_buffer);
-    sound_buffer.dwBufferBytes = size;
-    sound_buffer.lpwfxFormat = &wavfmt;
-    sound_buffer.dwFlags = DSBCAPS_LOCSOFTWARE  | DSBCAPS_GLOBALFOCUS;
-
-    hr = IDirectSound_CreateSoundBuffer( lpDS, &sound_buffer, &samples[drivenum][samplenum], NULL );
-    if (hr != DS_OK) {
-        write_log ("DRIVESOUND: Secondary CreateSoundBuffer(%s) failure: %s\n",
-           path, DXError (hr));
-        goto error;
-    }
-    hr = IDirectSoundBuffer_Lock (samples[drivenum][samplenum], 0, sndbufsize, &b1, &s1, &b2, &s2, DSBLOCK_ENTIREBUFFER);
-    if (hr != DS_OK) {
-        write_log ("DRIVESOUND: lock failed: %s\n", DXError (hr));
-        goto error;
-    }
-    memcpy (b1, buf, size >= s1 ? s1 : size);
-    if (b2)
-        memcpy (b2, buf + s1, size - s1);
-    IDirectSoundBuffer_Unlock (samples[drivenum][samplenum], b1, s1, b2, s2);
-    write_log ("DRIVESOUND: drive %d, sample %d (%s) loaded\n", drivenum, samplenum, path);
-
-    return 1;
-    error:
-    free (buf);
-    if (samples[drivenum][samplenum]) {
-       IDirectSound_Release (samples[drivenum][samplenum]);
-       samples[drivenum][samplenum] = 0;
-    }
-    return 0;
-}
-
-
-static int open_audio_ds (void)
-{
-    HRESULT hr;
-    int freq = currprefs.sound_freq;
-    
-    enumerate_sound_devices (0);
-    hr = DirectSoundCreate (&sound_device_guid[currprefs.win32_soundcard], &lpDS, NULL);
-    if (hr != DS_OK)  {
-        write_log ("SOUND: DirectSoundCreate() failure: %s\n", DXError (hr));
-        return 0;
-    }
-    hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_NORMAL);
-    if (hr != DS_OK) {
-        write_log ("SOUND: Can't set cooperativelevel: %s\n", DXError (hr));
-        goto error;
-    }
-
-    createsample(0, DRIVESOUND_CLICK, "drive_click.raw");
-    createsample(0, DRIVESOUND_STARTUP, "drive_startup.raw");
-    createsample(0, DRIVESOUND_SPIN, "drive_spin.raw");
-    drive_enabled[0] = 1;    
-
-    drivesound_enabled = 1;
-
-    return 1;
-
-error:
-    close_audio_ds ();
-    return 0;
-}
-
-int drivesound_init (void)
-{
-    return open_audio_ds ();
-}
-
-void drivesound_free (void)
-{
-    close_audio_ds ();
-}
-
-void drivesound_click (int num, int delay)
-{
-    HRESULT hr;
-    LPDIRECTSOUNDBUFFER dsb;
-
-    if (!drivesound_enabled || !drive_enabled[num])
-       return;
-    dsb = samples[num][DRIVESOUND_CLICK];
-    if (!dsb)
-       return;
-    hr = IDirectSoundBuffer_SetCurrentPosition (dsb, 0);
-    hr = IDirectSoundBuffer_Play (dsb, 0, 0, 0);
-}
-
-void drivesound_motor (int num, int status)
-{
-    HRESULT hr;
-
-    if (!drivesound_enabled || !drive_enabled[num])
-       return;
-    if (!status) {
-       if (samples[num][DRIVESOUND_STARTUP])
-           hr = IDirectSoundBuffer_Stop (samples[num][DRIVESOUND_STARTUP]);
-       if (samples[num][DRIVESOUND_SPIN])
-           hr = IDirectSoundBuffer_Stop (samples[num][DRIVESOUND_SPIN]);
-    } else {
-       if (status == 2 && samples[num][DRIVESOUND_STARTUP])
-           hr = IDirectSoundBuffer_Play (samples[num][DRIVESOUND_STARTUP], 0, 0, 0);
-       if (samples[num][DRIVESOUND_SPIN])
-           hr = IDirectSoundBuffer_Play (samples[num][DRIVESOUND_SPIN], 0, 0, DSBPLAY_LOOPING);
-    }
-}
index a458c5e6d54605555ee12b55bbd93f3105dea647..b33d203481e8cd6076897b7eeb0372c08221c252 100755 (executable)
@@ -887,8 +887,8 @@ IDI_MEMORY              ICON                    "chip.ico"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,8,26,0
- PRODUCTVERSION 0,8,26,0
+ FILEVERSION 0,8,27,0
+ PRODUCTVERSION 0,8,27,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -904,12 +904,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "0.8.26"
+            VALUE "FileVersion", "0.8.27"
             VALUE "InternalName", "WinUAE"
             VALUE "LegalCopyright", "© 1996-2004 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "0.8.26"
+            VALUE "ProductVersion", "0.8.27"
         END
     END
     BLOCK "VarFileInfo"
index 8865f05a3f36730f66f341835b2b86dbfcf34134..86bd5e6b0e3fa94fab06e64553d6b4cfc72c30c6 100755 (executable)
@@ -599,7 +599,7 @@ static void filtercheck (uae_s16 *sndbuffer, int len)
 
 void finish_sound_buffer (void)
 {
-    if (!have_sound || turbo_emulation)
+    if (turbo_emulation)
        return;
     filtercheck ((uae_s16*)sndbuffer, sndbufsize / 2);
 #ifdef DRIVESOUND
@@ -608,9 +608,11 @@ void finish_sound_buffer (void)
 #ifdef AVIOUTPUT
     if (avioutput_audio)
         AVIOutput_WriteAudio ((uae_u8*)sndbuffer, sndbufsize);
-    if (!avioutput_framelimiter && (avioutput_video || avioutput_audio))
+    if (avioutput_enabled && !avioutput_framelimiter)
        return;
 #endif
+    if (!have_sound)
+       return;
     finish_sound_buffer_ds ();
 }
 
index 0e67f38749df63de58349ac7c922dea0d04e0321..a35201b6ba287eceffa26f8912ff429ad3d1aab1 100755 (executable)
@@ -21,7 +21,7 @@ extern int manual_painting_needed;
 extern int manual_palette_refresh_needed;
 extern int mouseactive, focus;
 #define WINUAEBETA 1
-#define WINUAEBETASTR " Beta 3"
+#define WINUAEBETASTR " Beta 4"
 
 extern void my_kbd_handler (int, int, int);
 extern void clearallkeys(void);
index f902f78fb0c749932a8394e8b562f1abf0324210..b79150c8a67929693a21f045030238aab42b2387 100755 (executable)
@@ -5541,9 +5541,9 @@ static void enable_for_avioutputdlg(HWND hDlg)
 {
 #if defined (PROWIZARD)
        EnableWindow( GetDlgItem( hDlg, IDC_PROWIZARD ), TRUE );
-#endif
        if (full_property_sheet)
            EnableWindow( GetDlgItem( hDlg, IDC_PROWIZARD ), FALSE );
+#endif
 
        EnableWindow(GetDlgItem(hDlg, IDC_SCREENSHOT), full_property_sheet ? FALSE : TRUE);
 
@@ -5579,6 +5579,7 @@ static void enable_for_avioutputdlg(HWND hDlg)
                WIN32GUI_LoadUIString (IDS_AVIOUTPUT_NOCODEC, aviout_videoc, sizeof (aviout_videoc));
        }
        SetWindowText(GetDlgItem(hDlg, IDC_AVIOUTPUT_VIDEO_STATIC), aviout_videoc);
+       EnableWindow(GetDlgItem(hDlg, IDC_AVIOUTPUT_ACTIVATED), (!avioutput_audio && !avioutput_video) ? FALSE : TRUE);
 }
 
 static BOOL CALLBACK AVIOutputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -5689,6 +5690,10 @@ static BOOL CALLBACK AVIOutputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                                avioutput_video = 1;
                                                strcpy (aviout_videoc, string);
                                                SetWindowText(GetDlgItem(hDlg, IDC_AVIOUTPUT_VIDEO_STATIC), string);
+                                               if (avioutput_audio == AVIAUDIO_WAV) {
+                                                   avioutput_audio = 0;
+                                                   aviout_audioc[0] = 0;
+                                               }
                                        }
                                        else
                                                avioutput_video = 0;
@@ -5725,7 +5730,9 @@ static BOOL CALLBACK AVIOutputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                        break;
                                if (ofn.nFilterIndex == 2) {
                                    avioutput_audio = AVIAUDIO_WAV;
-                                   SetWindowText(GetDlgItem(hDlg, IDC_AVIOUTPUT_AUDIO_STATIC), "Wave (internal)");
+                                   avioutput_video = 0;
+                                   aviout_videoc[0] = 0;
+                                   strcpy (aviout_audioc, "Wave (internal)");
                                    if (strlen (avioutput_filename) > 4 && !stricmp (avioutput_filename + strlen (avioutput_filename) - 4, ".avi"))
                                        strcpy (avioutput_filename + strlen (avioutput_filename) - 4, ".wav");
                                }