--- uae/src/custom.c 2018/04/24 16:47:31 1.1.1.7 +++ uae/src/custom.c 2018/04/24 16:48:49 1.1.1.8 @@ -125,7 +125,7 @@ static unsigned int ddfstrt, ddfstop; static uae_u32 dskpt; static uae_u16 dsklen, dsksync; -static int dsklength; +static int dsklength, syncfound; /* The display and data fetch windows */ @@ -165,7 +165,7 @@ static struct copper cop_state; static void prepare_copper_1 (void); -int dskdmaen; /* used in cia.c */ +static int dskdmaen; /* * Statistics @@ -253,7 +253,7 @@ void reset_frame_rate_hack (void) write_log ("Resetting frame rate hack\n"); } -static __inline__ void prepare_copper (void) +STATIC_INLINE void prepare_copper (void) { if (cop_state.vpos > vpos || cop_state.state == COP_stop) @@ -279,7 +279,7 @@ void check_prefs_changed_custom (void) } -static __inline__ void setclr (uae_u16 *p, uae_u16 val) +STATIC_INLINE void setclr (uae_u16 *p, uae_u16 val) { if (val & 0x8000) *p |= val & 0x7FFF; @@ -292,7 +292,7 @@ __inline__ int current_hpos (void) return cycles - eventtab[ev_hsync].oldcycles; } -static __inline__ uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount) +STATIC_INLINE uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount) { if (!chipmem_bank.check (plpt, bytecount)) { static int count = 0; @@ -303,7 +303,7 @@ static __inline__ uae_u8 *pfield_xlatept return chipmem_bank.xlateaddr (plpt); } -static __inline__ void docols (struct color_entry *colentry) +STATIC_INLINE void docols (struct color_entry *colentry) { #if AGA_CHIPSET == 0 int i; @@ -400,7 +400,7 @@ static void decide_diw (int hpos) /* Called when we know that the line is not in the border and we want to draw * it. The data fetch starting position and length are passed as parameters. */ -static __inline__ void decide_as_playfield (int startpos, int len) +STATIC_INLINE void decide_as_playfield (int startpos, int len) { thisline_decision.which = 1; @@ -501,7 +501,7 @@ static void adjust_broken_program (int h } } -static __inline__ void set_decided_res (void) +STATIC_INLINE void set_decided_res (void) { decided_res = RES_LORES; if (bplcon0 & 0x8000) @@ -510,7 +510,7 @@ static __inline__ void set_decided_res ( decided_res = RES_SUPERHIRES; } -static __inline__ void post_decide_line (int hpos) +STATIC_INLINE void post_decide_line (int hpos) { if (thisline_decision.which == 1 && hpos < thisline_decision.plfstrt + thisline_decision.plflinelen @@ -625,7 +625,7 @@ static void decide_line_1 (int hpos) /* Main entry point for deciding how to draw a line. May either do * nothing, decide the line as border, or decide the line as playfield. */ -static __inline__ void decide_line (int hpos) +STATIC_INLINE void decide_line (int hpos) { if (thisline_decision.which == 0 && hpos >= plfstrt) decide_line_1 (hpos); @@ -846,7 +846,7 @@ static void do_modulos (int hpos) } } -static __inline__ void record_sprite (int spr, int sprxp) +STATIC_INLINE void record_sprite (int spr, int sprxp) { int pos = next_sprite_draw; unsigned int data, datb; @@ -1297,7 +1297,7 @@ void togglemouse (void) } } -static __inline__ int adjust (int val) +STATIC_INLINE int adjust (int val) { if (val > 127) return 127; @@ -1400,7 +1400,7 @@ static uae_u32 timehack_helper (void) /* * register functions */ -static __inline__ uae_u16 DENISEID (void) +STATIC_INLINE uae_u16 DENISEID (void) { if (currprefs.chipset_mask & CSMASK_AGA) return 0xF8; @@ -1408,12 +1408,12 @@ static __inline__ uae_u16 DENISEID (void return 0xFC; return 0xFFFF; } -static __inline__ uae_u16 DMACONR (void) +STATIC_INLINE uae_u16 DMACONR (void) { return (dmacon | (bltstate==BLT_done ? 0 : 0x4000) | (blt_info.blitzero ? 0x2000 : 0)); } -static __inline__ uae_u16 INTENAR (void) +STATIC_INLINE uae_u16 INTENAR (void) { return intena; } @@ -1421,11 +1421,11 @@ uae_u16 INTREQR (void) { return intreq | (currprefs.use_serial ? 0x0001 : 0); } -static __inline__ uae_u16 ADKCONR (void) +STATIC_INLINE uae_u16 ADKCONR (void) { return adkcon; } -static __inline__ uae_u16 VPOSR (void) +STATIC_INLINE uae_u16 VPOSR (void) { unsigned int csbit = ntscmode ? 0x1000 : 0; csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; @@ -1443,15 +1443,15 @@ static void VPOSW (uae_u16 v) */ } -static __inline__ uae_u16 VHPOSR (void) +STATIC_INLINE uae_u16 VHPOSR (void) { return (vpos << 8) | current_hpos(); } -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_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 COPJMP1 (uae_u16 a) { @@ -1483,7 +1483,7 @@ static void COPJMP2 (uae_u16 a) events_schedule (); } -static __inline__ void COPCON (uae_u16 a) +STATIC_INLINE void COPCON (uae_u16 a) { copcon = a; } @@ -1513,6 +1513,10 @@ static void DMACON (uae_u16 v) abort (); need_resched = 1; } + if ((dmacon & DMA_DISK) > (oldcon & DMA_DISK)) { + DISK_reset_cycles (); + } + if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) { static int count = 0; if (!count) { @@ -1552,7 +1556,7 @@ static void DMACON (uae_u16 v) /*static int trace_intena = 0;*/ -static __inline__ void INTENA (uae_u16 v) +STATIC_INLINE void INTENA (uae_u16 v) { /* if (trace_intena) fprintf (stderr, "INTENA: %04x\n", v);*/ @@ -1627,7 +1631,7 @@ static void BPLCON0 (int hpos, uae_u16 v post_decide_line (hpos); } -static __inline__ void BPLCON1 (int hpos, uae_u16 v) +STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) { if (bplcon1 == v) return; @@ -1635,21 +1639,21 @@ static __inline__ void BPLCON1 (int hpos bplcon1 = v; decide_delay (hpos); } -static __inline__ void BPLCON2 (int hpos, uae_u16 v) +STATIC_INLINE void BPLCON2 (int hpos, uae_u16 v) { if (bplcon2 == v) return; decide_line (hpos); bplcon2 = v; } -static __inline__ void BPLCON3 (int hpos, uae_u16 v) +STATIC_INLINE void BPLCON3 (int hpos, uae_u16 v) { if (bplcon3 == v) return; decide_line (hpos); bplcon3 = v; } -static __inline__ void BPLCON4 (int hpos, uae_u16 v) +STATIC_INLINE void BPLCON4 (int hpos, uae_u16 v) { if (! (currprefs.chipset_mask & CSMASK_AGA)) return; @@ -1678,14 +1682,14 @@ static void BPL2MOD (int hpos, uae_u16 v } /* We could do as well without those... */ -static __inline__ void BPL1DAT (uae_u16 v) { bpl1dat = v; } -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_INLINE void BPL1DAT (uae_u16 v) { bpl1dat = v; } +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) { @@ -1833,7 +1837,7 @@ static void BLTSIZH (uae_u16 v) do_blitter (); } -static __inline__ void SPRxCTL_1 (uae_u16 v, int num) +STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num) { int sprxp; sprctl[num] = v; @@ -1850,7 +1854,7 @@ static __inline__ void SPRxCTL_1 (uae_u1 sprvstart[num] = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); sprvstop[num] = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100); } -static __inline__ void SPRxPOS_1 (uae_u16 v, int num) +STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num) { int sprxp; sprpos[num] = v; @@ -1858,13 +1862,13 @@ static __inline__ void SPRxPOS_1 (uae_u1 sprxpos[num] = sprxp; sprvstart[num] = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); } -static __inline__ void SPRxDATA_1 (uae_u16 v, int num) +STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num) { sprdata[num] = v; nr_armed += 1 - sprarmed[num]; sprarmed[num] = 1; } -static __inline__ void SPRxDATB_1 (uae_u16 v, int num) +STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num) { sprdatb[num] = v; } @@ -1970,36 +1974,73 @@ static void DSKLEN (uae_u16 v) write_log ("warning: Disk DMA aborted!\n"); eventtab[ev_diskblk].active = 0; events_schedule(); - } dsklen = dsklength = v; dsklength &= 0x3fff; if (dskdmaen == 2 && dsksync != 0x4489 && (adkcon & 0x400)) { write_log ("Non-standard sync: %04x len: %x\n", dsksync, dsklength); } - if (dskdmaen > 1) { - if (dsklen & 0x4000) { - eventtab[ev_diskblk].active = 1; - eventtab[ev_diskblk].oldcycles = cycles; - eventtab[ev_diskblk].evtime = 40 + cycles; /* ??? */ - events_schedule(); - } else { - int result = DISK_PrepareReadMFM(dsklength, dsksync, adkcon & 0x400); - if (result) { - eventtab[ev_diskblk].active = 1; - eventtab[ev_diskblk].oldcycles = cycles; - eventtab[ev_diskblk].evtime = result + cycles; - events_schedule(); - } - } + if (dskdmaen <= 1) + return; + + if (dsklen & 0x4000) { + eventtab[ev_diskblk].active = 1; + eventtab[ev_diskblk].oldcycles = cycles; + eventtab[ev_diskblk].evtime = 40 + cycles; /* ??? */ + events_schedule(); + dskdmaen = 3; + } else { + DISK_StartRead (); + syncfound = !(adkcon & 0x400); + } +} + +static int update_disk_reads (void) +{ + int retval = 0; + /* If we get called from DSKBYTR or DSKDATR, we may not actually be + reading from disk, so skip the DMA update. */ + if (dskdmaen != 2) { + DISK_update_reads (0, 0, 0, 0); + return 0; + } + if (dsklength == 0) + write_log ("Bug in disk code: dsklength == 0\n"); + else + retval = DISK_update_reads (&dskpt, &dsklength, &syncfound, dsksync); + + if (dsklength == 0) { + dskdmaen = -1; + /* DISKBLK */ + INTREQ (0x8002); } + return retval; +} + +static void disksync_handler (void) +{ + uae_u16 mfm, byte; + /* If no DMA, something weird happened. It's not clear what to do + about it. */ + if (! dmaen (0x10) || dskdmaen != 2) + return; + + /* Likewise... */ + if (! update_disk_reads ()) + return; + DISK_GetData (&mfm, &byte); + + if (dsksync == mfm) + INTREQ (0x9000); + eventtab[ev_disksync].active = 0; } static uae_u16 DSKBYTR (void) { uae_u16 v = (dsklen >> 1) & 0x6000; uae_u16 mfm, byte; - if (DISK_GetData (&mfm, &byte)) + if (update_disk_reads ()) v |= 0x8000; + DISK_GetData (&mfm, &byte); v |= byte; if (dsksync == mfm) v |= 0x1000; @@ -2009,6 +2050,7 @@ static uae_u16 DSKBYTR (void) static uae_u16 DSKDATR (void) { uae_u16 mfm, byte; + update_disk_reads (); DISK_GetData (&mfm, &byte); return mfm; } @@ -2084,7 +2126,7 @@ static void JOYTEST (uae_u16 v) * Here starts the copper code. Can you believe it used to be worse? */ -static __inline__ void copper_adjust_diw (struct copper *cst) +STATIC_INLINE void copper_adjust_diw (struct copper *cst) { if (cst->vdiw == DIW_waiting_start && vpos == plffirstline) cst->vdiw = DIW_waiting_stop; @@ -2110,13 +2152,13 @@ static unsigned int waitmasktab[256]; #define COP_OFFSET 4 -static __inline__ int copper_in_playfield (enum diw_states diw, int hpos) +STATIC_INLINE int copper_in_playfield (enum diw_states diw, int hpos) { hpos -= COP_OFFSET; return diw == DIW_waiting_stop && hpos >= plfstrt && hpos < plfstrt + plflinelen; } -static __inline__ int copper_cant_read (enum diw_states diw, int hpos, int planes) +STATIC_INLINE int copper_cant_read (enum diw_states diw, int hpos, int planes) { int t; @@ -2309,7 +2351,7 @@ static void update_copper_1 (int until_h cop_state.vpos = c_vpos; } -static __inline__ void update_copper (int until_hpos) +STATIC_INLINE void update_copper (int until_hpos) { if (cop_state.vpos > vpos || cop_state.hpos > until_hpos @@ -2526,13 +2568,13 @@ static void diskblk_handler (void) void do_disk (void) { - if (dskdmaen != 2 && (regs.spcflags & SPCFLAG_DISK)) { + if (dskdmaen != 3 && (regs.spcflags & SPCFLAG_DISK)) { static int warned = 0; if (!warned) warned++, write_log ("BUG!\n"); return; } - if (dmaen(0x10)){ + if (dmaen (0x10)){ if (dsklen & 0x4000) { if (!chipmem_bank.check (dskpt, 2*dsklength)) { write_log ("warning: Bad disk write DMA pointer\n"); @@ -2548,8 +2590,6 @@ void do_disk (void) } DISK_WriteData(dsklength); } - } else { - DISK_ReadMFM (dskpt); } regs.spcflags &= ~SPCFLAG_DISK; INTREQ(0x9002); @@ -2826,7 +2866,12 @@ static void hsync_handler (void) eventtab[ev_hsync].evtime += cycles - eventtab[ev_hsync].oldcycles; eventtab[ev_hsync].oldcycles = cycles; - CIA_hsync_handler(); + CIA_hsync_handler (); + + if (dskdmaen == 2 && dmaen (0x10)) { + update_disk_reads (); + DISK_search_sync (maxhpos, dsksync); + } if (currprefs.produce_sound > 0) { int nr; @@ -2914,6 +2959,8 @@ static void init_eventtab (void) eventtab[ev_diskblk].active = 0; eventtab[ev_diskindex].handler = diskindex_handler; eventtab[ev_diskindex].active = 0; + eventtab[ev_disksync].handler = disksync_handler; + eventtab[ev_disksync].active = 0; events_schedule (); }