This commit is contained in:
Toni Wilen 2014-02-02 17:57:49 +02:00
parent 9028b9456b
commit 5824a72326
37 changed files with 1774 additions and 307 deletions

16
cia.cpp
View File

@ -76,7 +76,7 @@ static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
static int ciaatlatch, ciabtlatch;
static bool oldled, oldovl, oldcd32mute;
static bool oldovl, oldcd32mute;
static bool led;
static int led_old_brightness;
static unsigned long led_cycles_on, led_cycles_off, led_cycle;
@ -853,7 +853,7 @@ void CIAA_tod_inc (int cycles)
event2_newevent_xx (-1, cycles + TOD_INC_DELAY, 0, CIAA_tod_handler);
}
static void bfe001_change (void)
static void check_led (void)
{
uae_u8 v = ciaapra;
bool led2;
@ -865,6 +865,12 @@ static void bfe001_change (void)
led = led2;
led_old_brightness = -1;
}
}
static void bfe001_change (void)
{
uae_u8 v = ciaapra;
check_led ();
if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
oldovl = v & 1;
if (!oldovl) {
@ -1119,6 +1125,10 @@ static uae_u8 ReadCIAB (unsigned int addr)
case 12:
return ciabsdr;
case 13:
#if CIAB_DEBUG_IRQ
if (ciabicr & (0x80 | 0x40))
write_log (_T("CIAB IRQ cleared\n"));
#endif
tmp = ciabicr & ~0x40;
ciabicr = 0;
return tmp;
@ -1482,7 +1492,6 @@ void CIA_reset (void)
kblostsynccnt = 0;
serbits = 0;
oldcd32mute = 1;
oldled = true;
resetwarning_phase = resetwarning_timer = 0;
heartbeat_cnt = 0;
ciab_tod_event_state = 0;
@ -1506,6 +1515,7 @@ void CIA_reset (void)
DISK_select_set (ciabprb);
}
map_overlay (0);
check_led ();
#ifdef SERIAL_PORT
if (currprefs.use_serial && !savestate_state)
serial_dtr_off (); /* Drop DTR at reset */

View File

@ -64,7 +64,7 @@
#define CUSTOM_DEBUG 0
#define SPRITE_DEBUG 0
#define SPRITE_DEBUG_MINY 0x0
#define SPRITE_DEBUG_MINY 246
#define SPRITE_DEBUG_MAXY 0x300
#define SPR0_HPOS 0x15
#define MAX_SPRITES 8
@ -389,7 +389,6 @@ static uae_u32 thisline_changed;
static struct decision thisline_decision;
static int fetch_cycle, fetch_modulo_cycle;
static int bitplane_dma_turned_on;
enum plfstate
{
@ -399,10 +398,17 @@ enum plfstate
plf_wait_stop,
plf_passed_stop,
plf_passed_stop2,
plf_end,
plf_finished
plf_end
} plf_state;
enum plfrenderstate
{
plfr_idle,
plfr_active,
plfr_end,
plfr_finished
} plfr_state;
enum fetchstate {
fetch_not_started,
fetch_started_first,
@ -492,6 +498,7 @@ void alloc_cycle_blitter (int hpos, uaecptr *ptr, int chnum)
if (warned > 0) {
write_log (_T("buggy copper cycle conflict with blitter ch %c %08x <- %08x PC=%08x\n"), 'A' + (chnum - 1), *ptr, srcptr, m68k_getpc ());
warned--;
//activate_debugger ();
}
if ((currprefs.cs_hacks & 1) && currprefs.cpu_model == 68000)
*ptr = srcptr;
@ -918,9 +925,10 @@ static uae_u64 fetched_aga[MAX_PLANES];
/* Expansions from bplcon0/bplcon1. */
static int toscr_res, toscr_res2p;
static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, fetchwidth;
static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, toscr_nr_planes_shifter;
static int fetchwidth;
static int toscr_delay[2], toscr_delay_adjusted[2];
static int delay_cycles, delay_lastcycle;
static int delay_cycles, delay_lastcycle[2];
static bool bplcon1_written;
/* The number of bits left from the last fetched words.
@ -1009,6 +1017,17 @@ STATIC_INLINE int is_bitplane_dma_inline (int hpos)
return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
}
static int islinetoggle (void)
{
int linetoggle = 0;
if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
} else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) {
linetoggle = 1; // hardwired NTSC Agnus
}
return linetoggle;
}
/* Expand bplcon0/bplcon1 into the toscr_xxx variables. */
static void compute_toscr_delay (int bplcon1)
{
@ -1035,6 +1054,14 @@ static void compute_toscr_delay (int bplcon1)
#endif
}
static void set_delay_lastcycle (void)
{
delay_lastcycle[0] = ((maxhpos + 1) * 2 + 0) << bplcon0_res;
delay_lastcycle[1] = delay_lastcycle[0];
if (islinetoggle ())
delay_lastcycle[1]++;
}
static int bpldmasetuphpos, bpldmasetuphpos_diff;
static int bpldmasetupphase;
static void update_toscr_planes (int fm);
@ -1069,7 +1096,7 @@ static void setup_fmodes (int hpos)
fetchmode_size = 16 << fetchmode;
fetchmode_bytes = 2 << fetchmode;
fetchmode_mask = fetchmode_size - 1;
delay_lastcycle = (maxhpos * 2) << bplcon0_res;
set_delay_lastcycle ();
compute_toscr_delay (bplcon1);
if (thisline_decision.plfleft < 0) {
@ -1343,7 +1370,7 @@ STATIC_INLINE void do_delays_3_ecs (int nbits)
if (todisplay_fetched[oddeven] && dp == delay) {
for (int i = oddeven; i < MAX_PLANES; i += 2) {
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2) {
todisplay2[i] = todisplay[i];
}
todisplay_fetched[oddeven] = false;
@ -1359,7 +1386,7 @@ STATIC_INLINE void do_delays_3_ecs (int nbits)
do_tosrc (oddeven, 2, diff, 0);
nbits2 -= diff;
if (todisplay_fetched[oddeven]) {
for (int i = oddeven; i < MAX_PLANES; i += 2)
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2)
todisplay2[i] = todisplay[i];
todisplay_fetched[oddeven] = false;
}
@ -1382,7 +1409,8 @@ STATIC_INLINE void do_delays_fast_3_ecs (int nbits)
do_tosrc (0, 1, diff, 0);
nbits2 -= diff;
if (todisplay_fetched[0]) {
memcpy (todisplay2, todisplay, sizeof todisplay);
for (int i = 0; i < toscr_nr_planes_shifter; i++)
todisplay2[i] = todisplay[i];
todisplay_fetched[0] = false;
todisplay_fetched[1] = false;
}
@ -1404,7 +1432,7 @@ STATIC_INLINE void do_delays_3_aga (int nbits, int fm)
do_tosrc (oddeven, 2, diff, fm);
nbits2 -= diff;
if (todisplay_fetched[oddeven]) {
for (int i = oddeven; i < MAX_PLANES; i += 2)
for (int i = oddeven; i < toscr_nr_planes_shifter; i += 2)
todisplay2_aga[i] = todisplay_aga[i];
todisplay_fetched[oddeven] = false;
}
@ -1426,7 +1454,8 @@ STATIC_INLINE void do_delays_fast_3_aga (int nbits, int fm)
do_tosrc (0, 1, diff, fm);
nbits2 -= diff;
if (todisplay_fetched[0]) {
memcpy (todisplay2_aga, todisplay_aga, sizeof todisplay_aga);
for (int i = 0; i < toscr_nr_planes_shifter; i++)
todisplay2_aga[i] = todisplay_aga[i];
todisplay_fetched[0] = false;
todisplay_fetched[1] = false;
}
@ -1483,29 +1512,41 @@ STATIC_INLINE void do_delays_fast (int nbits, int fm)
}
}
static void toscr_right_edge (int nbits, int fm)
{
// Emulate hpos counter (delay_cycles) reseting at the end of scanline.
// (Result is ugly shift in graphics in far right overscan)
int diff = delay_lastcycle[lol] - delay_cycles;
int nbits2 = nbits;
if (nbits2 >= diff) {
do_delays (diff, fm);
nbits2 -= diff;
delay_cycles = 0;
toscr_delay[0] -= 2;
toscr_delay[0] &= fetchmode_mask;
toscr_delay[1] -= 2;
toscr_delay[1] &= fetchmode_mask;
}
if (nbits2) {
do_delays (nbits2, fm);
delay_cycles += nbits2;
}
}
STATIC_INLINE void toscr_1 (int nbits, int fm)
{
if (delay_cycles + nbits >= delay_lastcycle) {
// Emulate hpos counter (delay_cycles) reseting at the end of scanline.
// It can cause glitch in far right overscan.
int diff = delay_lastcycle - delay_cycles;
int nbits2 = nbits;
if (nbits2 >= diff) {
do_delays (diff, fm);
nbits2 -= diff;
delay_cycles = 0;
}
if (nbits2)
do_delays (nbits2, fm);
if (delay_cycles + nbits >= delay_lastcycle[lol]) {
toscr_right_edge (nbits, fm);
} else if (toscr_delay[0] == toscr_delay[1]) {
// Most common case.
do_delays_fast (nbits, fm);
delay_cycles += nbits;
} else {
do_delays (nbits, fm);
delay_cycles += nbits;
}
out_nbits += nbits;
delay_cycles += nbits;
if (out_nbits == 32) {
int i;
uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4;
@ -1571,26 +1612,21 @@ static int flush_plane_data (int fm)
i += 32 - out_nbits;
toscr_1 (32 - out_nbits, fm);
}
i += 32;
memset (todisplay, 0, sizeof todisplay);
if (fm)
memset (todisplay_aga, 0, sizeof todisplay_aga);
toscr_1 (16, fm);
toscr_1 (16, fm);
if (fm == 2) {
/* flush AGA full 64-bit shift register */
/* flush AGA full 64-bit shift register + possible data in todisplay */
i += 32;
toscr_1 (16, fm);
toscr_1 (16, fm);
i += 32;
toscr_1 (16, fm);
toscr_1 (16, fm);
}
memset (todisplay2, 0, sizeof todisplay2);
if (fm)
memset (todisplay2_aga, 0, sizeof todisplay2_aga);
return i >> (1 + toscr_res);
}
@ -1601,6 +1637,28 @@ STATIC_INLINE void flush_display (int fm)
toscr_nbits = 0;
}
static void update_denise_shifter_planes (int hpos)
{
int np = GET_PLANES (bplcon0d);
// if DMA has ended but there is still data waiting in todisplay,
// it must be flushed out before number of planes change
if (np < toscr_nr_planes_shifter && hpos > thisline_decision.plfright && thisline_decision.plfright && (todisplay_fetched[0] || todisplay_fetched[1])) {
int diff = (hpos - thisline_decision.plfright) << (1 + toscr_res);
while (diff >= 16) {
toscr_1 (16, fetchmode);
diff -= 16;
}
if (diff)
toscr_1 (diff, fetchmode);
thisline_decision.plfright += hpos - thisline_decision.plfright;
}
toscr_nr_planes_shifter = np;
if (isocs7planes ()) {
if (toscr_nr_planes_shifter < 6)
toscr_nr_planes_shifter = 6;
}
}
STATIC_INLINE void update_denise (int hpos)
{
int res = GET_RES_DENISE (bplcon0d);
@ -1620,6 +1678,7 @@ STATIC_INLINE void update_denise (int hpos)
} else {
toscr_nr_planes2 = toscr_nr_planes;
}
toscr_nr_planes_shifter = toscr_nr_planes2;
}
STATIC_INLINE void fetch_start (int hpos)
@ -1953,23 +2012,28 @@ static void do_long_fetch (int hpos, int nwords, int dma, int fm)
#endif
static void finish_last_fetch (int pos, int fm)
static void finish_last_fetch (int pos, int fm, bool reallylast)
{
if (thisline_decision.plfleft < 0)
return;
if (plf_state >= plf_end)
// if (reallylast)
// plf_state = plf_end;
if (plfr_state >= plfr_end)
return;
plf_state = plf_end;
plfr_state = plfr_end;
flush_display (fm);
// This may not be the last fetch, store current endpos for future use.
// There is at least one demo that has two DDFSTRT-DDFSTOP horizontal sections.
thisline_decision.plfright = pos;
if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
ddfstate = DIW_waiting_start;
fetch_state = fetch_not_started;
if (!reallylast) {
// This may not be the last fetch, store current endpos for future use.
// There is at least one demo that has two DDFSTRT-DDFSTOP horizontal sections.
thisline_decision.plfright = pos;
#if 1
if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
ddfstate = DIW_waiting_start;
fetch_state = fetch_not_started;
}
}
#endif
}
/* check special case where last fetch wraps to next line
* this makes totally corrupted and flickering display on
@ -1981,7 +2045,7 @@ static void maybe_finish_last_fetch (int pos, int fm)
bool done = false;
if (plf_state != plf_passed_stop2 || (fetch_state != fetch_started && fetch_state != fetch_started_first) || !dmaen (DMA_BITPLANE)) {
finish_last_fetch (pos, fm);
finish_last_fetch (pos, fm, true);
return;
}
do {
@ -2018,7 +2082,7 @@ static void maybe_finish_last_fetch (int pos, int fm)
default:
goto end;
}
break;
break;
}
fetch_cycle++;
toscr_nbits += toscr_res2p;
@ -2037,19 +2101,16 @@ static void maybe_finish_last_fetch (int pos, int fm)
}
end:
finish_last_fetch (pos, fm);
finish_last_fetch (pos, fm, true);
}
/* make sure fetch that goes beyond maxhpos is finished */
static void finish_final_fetch (void)
{
if (plf_state < plf_end) {
finish_last_fetch (maxhpos, fetchmode);
if (plf_state != plf_end)
return;
}
plf_state = plf_finished;
if (plfr_state < plf_end)
finish_last_fetch (maxhpos, fetchmode, true);
plfr_state = plfr_finished;
// This is really the end of scanline, we can finally flush all remaining data.
thisline_decision.plfright += flush_plane_data (fetchmode);
thisline_decision.plflinelen = out_offs;
@ -2059,18 +2120,20 @@ static void finish_final_fetch (void)
STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int fm)
{
if (plf_state < plf_passed_stop && pos == ddfstop_to_test)
plf_state = plf_passed_stop;
if (dma || (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
if (plf_state < plf_passed_stop && pos == ddfstop_to_test)
plf_state = plf_passed_stop;
if ((fetch_cycle & fetchunit_mask) == 0) {
if (plf_state == plf_passed_stop2) {
finish_last_fetch (pos, fm);
return 1;
}
if (plf_state == plf_passed_stop) {
plf_state = plf_passed_stop2;
} else if (plf_state == plf_passed_stop2) {
plf_state = plf_end;
if ((fetch_cycle & fetchunit_mask) == 0) {
if (plf_state == plf_passed_stop2) {
finish_last_fetch (pos, fm, false);
return 1;
}
if (plf_state == plf_passed_stop) {
plf_state = plf_passed_stop2;
} else if (plf_state == plf_passed_stop2) {
plf_state = plf_end;
}
}
}
@ -2187,6 +2250,17 @@ static void update_fetch_x (int until, int fm)
flush_display (fm);
}
STATIC_INLINE int get_ddfstop_to_test (int hpos)
{
/* We need an explicit test against HARD_DDF_STOP here to guard against
programs that move the DDFSTOP before our current position before we
reach it. */
int ddfstop_to_test = HARD_DDF_STOP;
if (ddfstop >= hpos && plfstop < ddfstop_to_test)
ddfstop_to_test = plfstop;
return ddfstop_to_test;
}
STATIC_INLINE void update_fetch (int until, int fm)
{
int pos;
@ -2197,13 +2271,7 @@ STATIC_INLINE void update_fetch (int until, int fm)
if (nodraw () || plf_state >= plf_end)
return;
/* We need an explicit test against HARD_DDF_STOP here to guard against
programs that move the DDFSTOP before our current position before we
reach it. */
ddfstop_to_test = HARD_DDF_STOP;
if (ddfstop >= last_fetch_hpos && plfstop < ddfstop_to_test)
ddfstop_to_test = plfstop;
ddfstop_to_test = get_ddfstop_to_test (last_fetch_hpos);
pos = last_fetch_hpos;
cycle_diagram_shift = last_fetch_hpos - fetch_cycle;
@ -2239,7 +2307,7 @@ STATIC_INLINE void update_fetch (int until, int fm)
}
// vdiw getting cleared mid-scan = fetches also stop
if (diwstate == DIW_waiting_start && plf_state < plf_wait_stop) {
if ((diwstate == DIW_waiting_start || !dma) && plf_state < plf_wait_stop) {
// ecs = continue at passed_stop
// ocs = line is done
if (currprefs.chipset_mask & CSMASK_ECS_AGNUS)
@ -2379,11 +2447,18 @@ static void start_bpl_dma (int hpos, int hstart)
#else
fetch_state = fetch_started;
#endif
plfr_state = plfr_active;
ddfstate = DIW_waiting_stop;
if (hstart >= get_ddfstop_to_test (hpos))
plf_state = plf_passed_stop;
if (!bpldmawasactive) {
plfstrt_sprite = plfstrt;
plfstrt_sprite = hstart;
// OCS Agnus needs at least 1 empty cycle between
// sprite fetch and bitplane cycle sequence start.
if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
plfstrt_sprite--;
fetch_cycle = 0;
update_denise (last_fetch_hpos);
if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) {
@ -2415,6 +2490,8 @@ static void start_bpl_dma (int hpos, int hstart)
update_fetch_x (hstart, fetchmode);
}
estimate_last_fetch_cycle (hstart);
last_fetch_hpos = hstart;
@ -2432,6 +2509,7 @@ static void start_bpl_dma (int hpos, int hstart)
#endif
}
#if 0
/* this may turn on datafetch if program turns dma on during the ddf */
static void maybe_start_bpl_dma (int hpos)
{
@ -2449,12 +2527,13 @@ static void maybe_start_bpl_dma (int hpos)
return;
if (hpos <= plfstrt)
return;
if (hpos > plfstop - fetchunit)
if (hpos >= plfstop)
return;
if (ddfstate != DIW_waiting_start)
plf_state = plf_passed_stop;
start_bpl_dma (hpos, hpos);
}
#endif
STATIC_INLINE bool cant_this_last_line (void)
{
@ -2484,34 +2563,58 @@ STATIC_INLINE void decide_line (int hpos)
return;
if (fetch_state == fetch_not_started) {
int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2;
if (last_decide_line_hpos < start && hpos >= start) {
if (plf_state == plf_idle || plf_state == plf_end)
plf_state = plf_start;
}
if ((diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) {
int ok = 0;
if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
if (plf_state == plf_start)
plf_state = plf_active;
if (plf_state == plf_active)
ok = 1;
/* hack warning.. Writing to DDFSTRT when DMA should start must be ignored
* (correct fix would be emulate this delay for every custom register, but why bother..) */
if (hpos - 2 == ddfstrt_old_hpos)
ok = 0;
}
if (ok && diwstate == DIW_waiting_stop) {
if (dmaen (DMA_BITPLANE) && bitplane_dma_turned_on + 4 < hpos) {
start_bpl_dma (hpos, plfstrt);
estimate_last_fetch_cycle (plfstrt);
bool dma = dmaen (DMA_BITPLANE) != 0;
bool dmaecs = dma || (currprefs.chipset_mask & CSMASK_ECS_AGNUS);
int bplstart = hpos;
// dma needs to be on when matching ddfstrt if OCS Agnus
if (dmaecs) {
int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2;
if (last_decide_line_hpos < start && hpos >= start) {
if (plf_state >= plf_passed_stop2 || plf_state == plf_idle) {
plf_state = plf_start;
}
last_decide_line_hpos = hpos;
}
}
if (diwstate == DIW_waiting_stop) {
if (dmaecs) {
if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
/* hack warning.. Writing to DDFSTRT when DMA should start must be ignored
* (correct fix would be emulate this delay for every custom register, but why bother..) */
if (plf_state == plf_start && hpos - 2 != ddfstrt_old_hpos)
plf_state = plf_active;
bplstart = plfstrt;
}
}
if (dmaecs) {
// did we just match ddfstop but missed ddfstrt? DMA starts from passed plfstop state.
if (last_decide_line_hpos > plfstrt && (plf_state == plf_active || plf_state == plf_wait_stop) && diwstate == DIW_waiting_stop) {
int stop = get_ddfstop_to_test (last_decide_line_hpos);
if (last_decide_line_hpos < stop && hpos >= stop) {
if (dma) {
// we did, fetches start!
bplstart = plfstop;
plf_state = plf_active;
} else {
// line done
plf_state = plf_end;
}
}
}
}
if (dma) {
if (plf_state == plf_active && (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) || hpos >= 0x18)) {
start_bpl_dma (hpos, bplstart);
last_decide_line_hpos = hpos;
#ifndef CUSTOM_SIMPLE
do_sprites (hpos);
do_sprites (hpos);
#endif
return;
return;
}
}
}
}
@ -3299,12 +3402,12 @@ static void reset_decisions (void)
reset_moddelays ();
reset_bplldelays ();
reset_dbplh_all (256);
bitplane_dma_turned_on = 0;
delay_cycles = 0;
compute_toscr_delay (bplcon1);
if (plf_state > plf_active)
plf_state = plf_idle;
if (plf_state == plf_active && !(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
if (plf_state >= plf_passed_stop2)
plf_state = plf_idle;
plfr_state = plfr_idle;
/* ECS/AGA and ddfstop > maxhpos == always-on display */
if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
@ -3315,7 +3418,16 @@ static void reset_decisions (void)
}
memset (outword, 0, sizeof outword);
memset (fetched, 0, sizeof fetched);
todisplay_fetched[0] = todisplay_fetched[1] = false;
memset (todisplay, 0, sizeof todisplay);
memset (todisplay2, 0, sizeof todisplay2);
#ifdef AGA
if (currprefs.chipset_mask & CSMASK_AGA) {
memset (todisplay_aga, 0, sizeof todisplay_aga);
memset (todisplay2_aga, 0, sizeof todisplay2_aga);
}
#endif
if (bitplane_line_crossing) {
// BPL1DAT would have been written after end of last scanline.
@ -3346,17 +3458,6 @@ static void reset_decisions (void)
#endif
}
static int islinetoggle (void)
{
int linetoggle = 0;
if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
} else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) {
linetoggle = 1; // hardwired NTSC Agnus
}
return linetoggle;
}
int vsynctimebase_orig;
void compute_vsynctime (void)
@ -3726,7 +3827,7 @@ void init_hz (bool fullinit)
vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);;
minfirstline = vsstop > vbstop ? vsstop : vbstop;
if (minfirstline > maxvpos / 2)
minfirstline = vsstop > vsstop ? vbstop : vsstop;
minfirstline = vsstop > vbstop ? vbstop : vsstop;
if (minfirstline < 2)
minfirstline = 2;
if (minfirstline >= maxvpos)
@ -3754,7 +3855,7 @@ void init_hz (bool fullinit)
if (vblank_hz > 300)
vblank_hz = 300;
maxhpos_short = maxhpos;
delay_lastcycle = (maxhpos * 2) << bplcon0_res;
set_delay_lastcycle ();
if (beamcon0 & 0x80) {
if (hbstrt > maxhpos)
hsyncstartpos = hbstrt + 1;
@ -3894,7 +3995,7 @@ static uae_u32 REGPARAM2 timehack_helper (TrapContext *context)
/*
* register functions
*/
STATIC_INLINE uae_u16 DENISEID (int *missing)
static uae_u16 DENISEID (int *missing)
{
*missing = 0;
if (currprefs.cs_deniserev >= 0)
@ -4013,6 +4114,14 @@ static uae_u16 VPOSR (void)
return vp;
}
static void vposback (int oldvpos)
{
if (cop_state.state == COP_wait && oldvpos == cop_state.vcmp) {
copper_enabled_thisline = 0;
unset_special (SPCFLAG_COPPER);
}
}
static void VPOSW (uae_u16 v)
{
int oldvpos = vpos;
@ -4040,12 +4149,24 @@ static void VPOSW (uae_u16 v)
vpos = oldvpos;
}
static void VHPOSW (uae_u16 v)
{
int oldvpos = vpos;
#if 0
if (M68K_GETPC < 0xf00000 || 1)
write_log (_T("VHPOSW %04X PC=%08x\n"), v, M68K_GETPC);
#endif
#if 0
int hp = v & 0xff;
int oldhp = current_hpos ();
if (hp != oldhp) {
if (hp >= maxhpos)
hp = maxhpos - 1;
eventtab[ev_hsync].oldcycles = get_cycles () - hp * CYCLE_UNIT;
eventtab[ev_hsync].evtime = eventtab[ev_hsync].oldcycles + HSYNCTIME;
events_schedule ();
}
#endif
v >>= 8; // lets ignore hpos for now
vpos &= 0xff00;
@ -4055,6 +4176,10 @@ static void VHPOSW (uae_u16 v)
} else if (vpos < minfirstline && oldvpos < minfirstline) {
vpos = oldvpos;
}
#if 0
if (vpos < oldvpos)
vposback (oldvpos);
#endif
}
static uae_u16 VHPOSR (void)
@ -4281,10 +4406,16 @@ static void DMACON (int hpos, uae_u16 v)
if (changed & (DMA_MASTER | DMA_BITPLANE)) {
ddf_change = vpos;
if (dmaen (DMA_BITPLANE))
maybe_start_bpl_dma (hpos);
#if 0
if (dmaen (DMA_BITPLANE)) {
if (vpos == 0xba)
write_log (_T("*"));
// maybe_start_bpl_dma (hpos);
} else {
write_log (_T("!"));
}
#endif
}
events_schedule();
}
@ -4335,6 +4466,25 @@ STATIC_INLINE int use_eventmode (uae_u16 v)
return 0;
}
static void rethink_intreq (void)
{
serial_check_irq ();
rethink_cias ();
#ifdef A2065
rethink_a2065 ();
#endif
#ifdef A2091
rethink_a2091 ();
#endif
#ifdef CDTV
rethink_cdtv ();
#endif
#ifdef CD32
rethink_akiko ();
#endif
rethink_gayle ();
}
static void send_interrupt_do (uae_u32 v)
{
INTREQ_0 (0x8000 | (1 << v));
@ -4353,15 +4503,24 @@ void send_interrupt (int num, int delay)
}
}
static int int_recursive; // yes, bad idea.
static void send_intena_do (uae_u32 v)
{
intena_internal = v;
setclr (&intena_internal, v);
doint ();
int_recursive++;
rethink_intreq ();
int_recursive--;
}
static void send_intreq_do (uae_u32 v)
{
intreq_internal = v;
setclr (&intreq_internal, v);
doint ();
int_recursive++;
rethink_intreq ();
int_recursive--;
}
static void INTENA (uae_u16 v)
@ -4372,7 +4531,7 @@ static void INTENA (uae_u16 v)
if (!(v & 0x8000) && old == intena)
return;
if (use_eventmode (v)) {
event2_newevent_xx (-1, INT_PROCESSING_DELAY, intena, send_intena_do);
event2_newevent_xx (-1, INT_PROCESSING_DELAY, v, send_intena_do);
} else {
intena_internal = intena;
if (v & 0x8000)
@ -4395,56 +4554,52 @@ void INTREQ_f (uae_u16 v)
{
if (use_eventmode (v)) {
setclr (&intreq, v);
send_intreq_do (intreq);
send_intreq_do (v);
} else {
setclr (&intreq, v);
setclr (&intreq_internal, v);
}
}
void INTREQ_0 (uae_u16 v)
bool INTREQ_0 (uae_u16 v)
{
#if 0
if (!(v & 0x8000) && (v & (0x80 | 0x100 | 0x200 | 0x400) != 0x0780))
write_log (_T("audirq clear %04x %04x\n"), v, intreq);
#endif
uae_u16 old = intreq;
setclr (&intreq, v);
if (use_eventmode (v)) {
if (int_recursive) {
// don't add new event if this call came from send_intreq_do/rethink
// and intreq didn't change.
// it wouldn't make any difference except to slow down everything
if (old == intreq)
return false;
}
if ((use_eventmode (v) || event2_count)) {
// don't bother to waste time for interrupt queuing if nothing changes
// but only if we are sure there is no queued changes
// but only if we are sure there is no other queued changes
if (old == intreq && intreq_internal == intreq)
return;
event2_newevent_xx (-1, INT_PROCESSING_DELAY, intreq, send_intreq_do);
return false;
event2_newevent_xx (-1, INT_PROCESSING_DELAY, v, send_intreq_do);
return false;
} else {
uae_u16 old2 = intreq_internal;
intreq_internal = intreq;
if (intreq == old)
return;
if (v & 0x8000)
if (old == intreq && old2 == intreq_internal)
return false;
if ((v & 0x8000) || currprefs.cpu_cycle_exact)
doint ();
return true;
}
}
void INTREQ (uae_u16 data)
{
INTREQ_0 (data);
serial_check_irq ();
rethink_cias ();
#ifdef A2065
rethink_a2065 ();
#endif
#ifdef A2091
rethink_a2091 ();
#endif
#ifdef CDTV
rethink_cdtv ();
#endif
#ifdef CD32
rethink_akiko ();
#endif
rethink_gayle ();
if (INTREQ_0 (data))
rethink_intreq ();
}
static void ADKCON (int hpos, uae_u16 v)
@ -4601,6 +4756,8 @@ static void BPLCON0_Denise (int hpos, uae_u16 v, bool immediate)
#endif
if (thisline_decision.plfleft < 0)
update_denise (hpos);
else
update_denise_shifter_planes (hpos);
}
static void BPLCON0 (int hpos, uae_u16 v)
@ -4748,7 +4905,7 @@ static void BPLxDAT (int hpos, int num, uae_u16 v)
bpl1dat_written = true;
bpl1dat_written_at_least_once = true;
if (thisline_decision.plfleft < 0) {
thisline_decision.plfleft = hpos;
thisline_decision.plfleft = (hpos + 3) & ~1;
reset_bpl_vars ();
update_denise (hpos);
}
@ -6925,6 +7082,7 @@ static void hsync_scandoubler (void)
reset_decisions ();
plf_state = plf_idle;
plfr_state = plfr_idle;
// copy color changes
dip1 = curr_drawinfo + next_lineno - 1;

View File

@ -932,13 +932,22 @@ static bool diskfile_iswriteprotect (struct uae_prefs *p, const TCHAR *fname, in
return wrprot1;
}
static bool isrecognizedext (const TCHAR *name)
{
const TCHAR *ext = _tcsrchr (name, '.');
if (ext) {
if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img")))
return true;
}
return false;
}
static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake, bool forcedwriteprotect)
{
uae_u8 buffer[2 + 2 + 4 + 4];
trackid *tid;
int num_tracks, size;
int canauto;
const TCHAR *ext;
drive_image_free (drv);
DISK_validate_filename (p, fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
@ -954,13 +963,6 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
gui_disk_image_change (dnum, fname, drv->wrprot);
canauto = 0;
ext = _tcsrchr (fname, '.');
if (ext) {
if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img")))
canauto = 1;
}
if (!drv->motoroff) {
drv->dskready_up_time = DSKREADY_UP_TIME;
drv->dskready_down_time = 0;
@ -993,6 +995,12 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
zfile_fseek (drv->diskfile, 0, SEEK_SET);
}
canauto = 0;
if (isrecognizedext (fname))
canauto = 1;
if (!canauto && drv->diskfile && isrecognizedext (zfile_getname (drv->diskfile)))
canauto = 1;
if (drv->catweasel) {
drv->wrprot = true;

View File

@ -743,9 +743,6 @@ static int playfield_start, playfield_end;
static int real_playfield_start, real_playfield_end;
static int linetoscr_diw_start, linetoscr_diw_end;
static int native_ddf_left, native_ddf_right;
#if 0
static bool can_have_bordersprite;
#endif
static int pixels_offset;
static int src_pixel, ham_src_pixel;
@ -1567,13 +1564,49 @@ static void pfield_do_linetoscr (int start, int stop, bool blank)
}
// left or right border sprite
static void pfield_do_linetoscr_border (int start, int stop, bool blank)
// left or right AGA border sprite
static void pfield_do_linetoscr_bordersprite_aga (int start, int stop, bool blank)
{
bool old = issprites;
issprites = colors_for_drawing.bordersprite != 0;
pfield_do_linetoscr (start, stop, blank);
issprites = old;
if (res_shift == 0) {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_aga_spronly (LTPARMS); break;
}
} else if (res_shift == 2) {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_stretch2_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_stretch2_aga_spronly (LTPARMS); break;
}
} else if (res_shift == 1) {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_stretch1_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_stretch1_aga_spronly (LTPARMS); break;
}
} else if (res_shift == -1) {
if (currprefs.gfx_lores_mode) {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_shrink1f_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_shrink1f_aga_spronly (LTPARMS); break;
}
} else {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_shrink1_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_shrink1_aga_spronly (LTPARMS); break;
}
}
} else if (res_shift == -2) {
if (currprefs.gfx_lores_mode) {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_shrink2f_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_shrink2f_aga_spronly (LTPARMS); break;
}
} else {
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: src_pixel = linetoscr_16_shrink2_aga_spronly (LTPARMS); break;
case 4: src_pixel = linetoscr_32_shrink2_aga_spronly (LTPARMS); break;
}
}
}
}
static void dummy_worker (int start, int stop, bool blank)
@ -2411,7 +2444,12 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
}
}
do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno);
#ifdef AGA
if (dip_for_drawing->nr_sprites && colors_for_drawing.bordersprite)
do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr, lineno);
else
#endif
do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno);
if (dh == dh_emerg)
memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth);
@ -2462,21 +2500,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
#ifdef AGA
if (dosprites) {
int i;
for (i = 0; i < dip_for_drawing->nr_sprites; i++)
for (int i = 0; i < dip_for_drawing->nr_sprites; i++)
draw_sprites_aga (curr_sprite_entries + dip_for_drawing->first_sprite_entry + i, 1);
uae_u16 oxor = bplxor;
if (dp_for_drawing->ham_seen) {
int todraw_amiga = res_shift_from_window (visible_right_border - visible_left_border);
init_ham_decoding ();
memset (ham_linebuf + ham_decode_pixel, 0, todraw_amiga * sizeof (uae_u32));
}
if (dip_for_drawing->nr_color_changes) {
bplxor = 0;
do_color_changes (pfield_do_fill_line, pfield_do_linetoscr_border, lineno);
bplxor = oxor;
}
do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_bordersprite_aga, lineno);
#else
if (0) {
#endif

View File

@ -40,8 +40,6 @@ void events_schedule (void)
nextevent = currcycle + mintime;
}
static int iwas1 = 123, iwas2 = 123, ihandled = 123;
void do_cycles_slow (unsigned long cycles_to_add)
{
if ((pissoff -= cycles_to_add) >= 0)
@ -83,12 +81,13 @@ void do_cycles_slow (unsigned long cycles_to_add)
currcycle = nextevent;
for (i = 0; i < ev_max; i++) {
iwas1 = i;
if (eventtab[i].active && eventtab[i].evtime == currcycle) {
iwas2 = i;
ihandled = -1;
(*eventtab[i].handler)();
ihandled = 1;
if (eventtab[i].handler == NULL) {
gui_message(_T("eventtab[%d].handler is null!\n"), i);
eventtab[i].active = 0;
} else {
(*eventtab[i].handler)();
}
}
}
events_schedule ();

View File

@ -1238,7 +1238,7 @@ static void expamem_init_a2091 (void)
static void expamem_init_a4091 (void)
{
#ifdef NCR
ncr_init ();
ncr_autoconfig_init ();
#endif
}
static void expamem_init_gfxboard_memory (void)

View File

@ -163,6 +163,25 @@ filesys_init:
FSIN_explibok:
move.l d0,a4
; create fake configdev
exg a4,a6
jsr -$030(a6) ;expansion/AllocConfigDev
tst.l d0
beq.s .nocd
move.l d0,a0
lea start(pc),a1
move.l a1,d0
clr.w d0
move.l d0,32(a0)
move.l #65536,36(a0)
move.w #$0104,16(a0) ;type + product
move.w #2011,16+4(a0) ;manufacturer
moveq #1,d0
move.l d0,22(a0) ;serial
jsr -$01e(a6) ;expansion/AddConfigDev
.nocd
exg a4,a6
tst.l $10c(a5)
beq.w FSIN_none

View File

@ -45,6 +45,7 @@
#include "gayle.h"
#include "savestate.h"
#include "a2091.h"
#include "ncr_scsi.h"
#include "cdtv.h"
#include "sana2.h"
#include "bsdsocket.h"
@ -55,6 +56,7 @@
#include "blkdev.h"
#include "isofs_api.h"
#include "scsi.h"
#include "uaenative.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
@ -828,15 +830,25 @@ static void initialize_mountinfo (void)
gayle_add_ide_unit (uci->controller - HD_CONTROLLER_IDE0, uci);
allocuci (&currprefs, nr, -1);
} else if (uci->controller <= HD_CONTROLLER_SCSI6) {
if (currprefs.cs_mbdmac > 0) {
if (currprefs.cs_mbdmac == 1) {
#ifdef A2091
a3000_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
allocuci (&currprefs, nr, -1);
#endif
} else if (currprefs.cs_mbdmac == 2) {
#ifdef NCR
a4000t_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
allocuci (&currprefs, nr, -1);
#endif
} else if (currprefs.cs_a2091) {
#ifdef A2091
a2091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
allocuci (&currprefs, nr, -1);
#endif
} else if (currprefs.cs_a4091) {
#ifdef NCR
a4091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci);
allocuci (&currprefs, nr, -1);
#endif
} else if (currprefs.cs_cdtvscsi) {
#ifdef CDTV
@ -6289,6 +6301,9 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context)
#ifdef BSDSOCKET
resaddr = bsdlib_startup (resaddr);
#endif
#ifdef WITH_UAENATIVE
resaddr = uaenative_startup (resaddr);
#endif
#ifdef SCSIEMU
resaddr = scsidev_startup (resaddr);
#endif

View File

@ -1,13 +1,13 @@
db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
db(0x60); db(0x02); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0xe8);
db(0x00); db(0x00); db(0x08); db(0x84); db(0x00); db(0x00); db(0x00); db(0xe0);
db(0x00); db(0x00); db(0x02); db(0x44); db(0x00); db(0x00); db(0x00); db(0x24);
db(0x00); db(0x00); db(0x03); db(0x52); db(0x00); db(0x00); db(0x00); db(0x00);
db(0x00); db(0x00); db(0x13); db(0x76); db(0x43); db(0xfa); db(0x18); db(0x81);
db(0x60); db(0x02); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0b); db(0x20);
db(0x00); db(0x00); db(0x08); db(0xbc); db(0x00); db(0x00); db(0x00); db(0xe0);
db(0x00); db(0x00); db(0x02); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x24);
db(0x00); db(0x00); db(0x03); db(0x8a); db(0x00); db(0x00); db(0x00); db(0x00);
db(0x00); db(0x00); db(0x13); db(0xae); db(0x43); db(0xfa); db(0x18); db(0xb9);
db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
db(0x48); db(0xe7); db(0xe0); db(0xe2); db(0x30); db(0x3c); db(0xff); db(0x38);
db(0x72); db(0x11); db(0x61); db(0x00); db(0x17); db(0x6a); db(0x4e); db(0x90);
db(0x72); db(0x11); db(0x61); db(0x00); db(0x17); db(0xa2); db(0x4e); db(0x90);
db(0x4a); db(0x80); db(0x67); db(0x4c); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x40);
db(0x70); db(0x14); db(0x24); db(0x00); db(0x72); db(0x01); db(0x4e); db(0xae);
@ -22,17 +22,24 @@
db(0x20); db(0x68); db(0x00); db(0x02); db(0x2f); db(0x08); db(0x4e); db(0x90);
db(0x20); db(0x5f); db(0x58); db(0x8f); db(0x48); db(0xe7); db(0xff); db(0x7e);
db(0x22); db(0x4e); db(0x20); db(0x08); db(0x30); db(0x7c); db(0xff); db(0xb8);
db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x12); db(0xb8);
db(0x61); db(0x00); db(0x16); db(0x80); db(0x4c); db(0xdf); db(0x7e); db(0xff);
db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x12); db(0xf0);
db(0x61); db(0x00); db(0x16); db(0xb8); db(0x4c); db(0xdf); db(0x7e); db(0xff);
db(0x4e); db(0x75); db(0x00); db(0x00); db(0x08); db(0x00); db(0x00); db(0x02);
db(0x67); db(0x06); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0x00); db(0x00);
db(0x4e); db(0xf9); db(0x00); db(0xf0); db(0x00); db(0x00); db(0x00); db(0x00);
db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04);
db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00); db(0x16); db(0xc0);
db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x17); db(0xe2); db(0x70); db(0x24);
db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00); db(0x16); db(0xf8);
db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x18); db(0x1a); db(0x70); db(0x24);
db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x17); db(0xd2); db(0x70); db(0x00);
db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x18); db(0x0a); db(0x70); db(0x00);
db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
db(0xc9); db(0x4e); db(0x4e); db(0xae); db(0xff); db(0xd0); db(0x4a); db(0x80);
db(0x67); db(0x2c); db(0x20); db(0x40); db(0x43); db(0xfa); db(0xfe); db(0xe2);
db(0x20); db(0x09); db(0x42); db(0x40); db(0x21); db(0x40); db(0x00); db(0x20);
db(0x21); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x00); db(0x00); db(0x24);
db(0x31); db(0x7c); db(0x01); db(0x04); db(0x00); db(0x10); db(0x31); db(0x7c);
db(0x07); db(0xdb); db(0x00); db(0x14); db(0x70); db(0x01); db(0x21); db(0x40);
db(0x00); db(0x16); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0xc9); db(0x4e);
db(0x4a); db(0xad); db(0x01); db(0x0c); db(0x67); db(0x00); db(0x00); db(0x5c);
db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x34); db(0x22); db(0x3c);
db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
@ -106,7 +113,7 @@
db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x4c); db(0xdf);
db(0x07); db(0x03); db(0x4e); db(0x75); db(0x52); db(0x91); db(0x70); db(0x00);
db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00);
db(0xfc); db(0xe0); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01);
db(0xfc); db(0xa8); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01);
db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40);
db(0x41); db(0xfa); db(0x15); db(0x02); db(0x23); db(0x48); db(0x00); db(0x0a);
db(0x41); db(0xfa); db(0xfe); db(0xd2); db(0x23); db(0x48); db(0x00); db(0x0e);
@ -300,7 +307,7 @@
db(0x30); db(0x3c); db(0xff); db(0x18); db(0x61); db(0x00); db(0x0e); db(0x58);
db(0x4e); db(0x90); db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f);
db(0x4a); db(0x80); db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00);
db(0x17); db(0x70); db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf6); db(0x8e);
db(0x17); db(0x70); db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf6); db(0x56);
db(0x20); db(0x08); db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20);
db(0x70); db(0xff); db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07);
db(0x00); db(0x00); db(0x67); db(0x40); db(0x0c); db(0x03); db(0x00); db(0x80);
@ -757,7 +764,7 @@
db(0x48); db(0xe7); db(0xc0); db(0x80); db(0x30); db(0x3c); db(0xff); db(0x38);
db(0x72); db(0x66); db(0x61); db(0x00); db(0x00); db(0x0a); db(0x4e); db(0x90);
db(0x4c); db(0xdf); db(0x01); db(0x03); db(0x4e); db(0x75); db(0x41); db(0xfa);
db(0xe8); db(0x44); db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff);
db(0xe8); db(0x0c); db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff);
db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x69); db(0x6e); db(0x70); db(0x75);
db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65);
db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72); db(0x2e); db(0x64);

View File

@ -508,6 +508,13 @@ static const char *gen_nextibyte (int flags)
return buffer;
}
static void makefromsr (void)
{
printf ("\tMakeFromSR();\n");
if (using_ce || using_ce020)
printf ("\tregs.ipl_pin = intlev ();\n");
}
static void check_ipl (void)
{
if (using_ce || using_ce020)
@ -2794,7 +2801,7 @@ static void gen_opcode (unsigned long int opcode)
fill_prefetch_next ();
}
printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
printf ("\tMakeFromSR ();\n");
makefromsr ();
break;
case i_ANDSR:
printf ("\tMakeSR ();\n");
@ -2810,7 +2817,7 @@ static void gen_opcode (unsigned long int opcode)
fill_prefetch_next ();
}
printf ("\tregs.sr &= src;\n");
printf ("\tMakeFromSR ();\n");
makefromsr ();
break;
case i_SUB:
{
@ -3315,7 +3322,7 @@ static void gen_opcode (unsigned long int opcode)
addcycles000 (6);
printf ("\tregs.sr = src;\n");
}
printf ("\tMakeFromSR ();\n");
makefromsr ();
if (cpu_level <= 1) {
// 68000 does 2xprefetch
sync_m68k_pc ();
@ -3415,7 +3422,7 @@ static void gen_opcode (unsigned long int opcode)
genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
printf ("\tregs.sr = src;\n");
}
printf ("\tMakeFromSR ();\n");
makefromsr ();
printf ("\tm68k_setstopped ();\n");
sync_m68k_pc ();
// STOP does not prefetch anything
@ -3428,7 +3435,7 @@ static void gen_opcode (unsigned long int opcode)
printf ("\tsr = %s (4);\n", srcwi);
printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
printf ("\tregs.sr = sr;\n");
printf ("\tMakeFromSR ();\n");
makefromsr ();
printf ("\tm68k_setstopped();\n");
m68k_pc_offset += 4;
sync_m68k_pc ();
@ -3441,7 +3448,7 @@ static void gen_opcode (unsigned long int opcode)
genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
printf ("\tregs.sr = sr;\n");
setpc ("pc");
printf ("\tMakeFromSR ();\n");
makefromsr ();
} else if (cpu_level == 1 && using_prefetch) {
int old_brace_level = n_braces;
printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
@ -3458,7 +3465,8 @@ static void gen_opcode (unsigned long int opcode)
printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
pop_braces (old_brace_level);
printf ("\tregs.sr = newsr; MakeFromSR ();\n");
printf ("\tregs.sr = newsr;\n");
makefromsr ();
printf ("\tif (newpc & 1) {\n");
printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
printf ("\t\tgoto %s;\n", endlabelstr);
@ -3500,9 +3508,12 @@ static void gen_opcode (unsigned long int opcode)
printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
}
printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
printf ("\t\tregs.sr = newsr;\n");
makefromsr ();
printf ("}\n");
pop_braces (old_brace_level);
printf ("\tregs.sr = newsr; MakeFromSR ();\n");
printf ("\tregs.sr = newsr;\n");
makefromsr ();
printf ("\tif (newpc & 1) {\n");
printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
printf ("\t\tgoto %s;\n", endlabelstr);
@ -3620,7 +3631,7 @@ static void gen_opcode (unsigned long int opcode)
printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
printf ("\tregs.sr |= sr;\n");
setpc ("pc");
printf ("\tMakeFromSR ();\n");
makefromsr ();
printf ("\tif (m68k_getpc () & 1) {\n");
printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
setpc ("oldpc");
@ -3795,9 +3806,9 @@ static void gen_opcode (unsigned long int opcode)
curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA);
//genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
//genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
fill_prefetch_next ();
if (curi->smode == Ad8r || curi->smode == PC8r)
addcycles000 (2);
fill_prefetch_next ();
genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
break;
case i_PEA:
@ -4532,6 +4543,7 @@ static void gen_opcode (unsigned long int opcode)
printf ("else");
start_brace ();
printf ("\n");
get_prefetch_020 ();
if (cpu_level >= 4) {
// apparently 68040/060 needs to always write at the end of RMW cycle
printf ("\t");

View File

@ -118,24 +118,30 @@ static void out_linetoscr_decl (DEPTH_T bpp, HMODE_T hmode, int aga, int spr)
{
outlnf ("static int NOINLINE linetoscr_%s%s%s%s (int spix, int dpix, int dpix_end)",
get_depth_str (bpp),
get_hmode_str (hmode), aga ? "_aga" : "", spr ? "_spr" : "");
get_hmode_str (hmode), aga ? "_aga" : "", spr > 0 ? "_spr" : (spr < 0 ? "_spronly" : ""));
}
static void out_linetoscr_do_srcpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
{
if (aga && cmode != CMODE_DUALPF) {
if (spr)
outln ( " sprpix_val = pixdata.apixels[spix];");
outln ( " spix_val = pixdata.apixels[spix] ^ xor_val;");
} else if (cmode != CMODE_HAM) {
outln ( " spix_val = pixdata.apixels[spix];");
if (spr)
outln ( " sprpix_val = spix_val;");
if (spr < 0) {
outln ( " sprpix_val = 0;");
} else {
if (aga && cmode != CMODE_DUALPF) {
if (spr)
outln ( " sprpix_val = pixdata.apixels[spix];");
outln ( " spix_val = pixdata.apixels[spix] ^ xor_val;");
} else if (cmode != CMODE_HAM) {
outln ( " spix_val = pixdata.apixels[spix];");
if (spr)
outln ( " sprpix_val = spix_val;");
}
}
}
static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
{
if (spr < 0)
return;
if (aga && cmode == CMODE_HAM) {
outln ( " spix_val = ham_linebuf[spix];");
outln ( " dpix_val = CONVERT_RGB (spix_val);");
@ -171,6 +177,8 @@ static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_
static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
{
if (spr < 0)
return;
if (hmode == HMODE_HALVE1F) {
outln ( " {");
outln ( " uae_u32 tmp_val;");
@ -216,7 +224,7 @@ static void put_dpix (const char *var)
outlnf (" buf[dpix++] = %s;", var);
}
static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt)
static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt, int spr)
{
if (aga) {
if (cnt == 1) {
@ -325,8 +333,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
outln ( "while (dpix < dpix_end) {");
if (spr)
outln ( " uae_u32 sprpix_val;");
outln ( " uae_u32 spix_val;");
outln ( " uae_u32 dpix_val;");
if (spr >= 0) {
outln ( " uae_u32 spix_val;");
outln ( " uae_u32 dpix_val;");
}
outln ( " uae_u32 out_val;");
outln ( "");
@ -334,7 +344,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr);
out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr);
outln ( " out_val = dpix_val;");
if (spr >= 0)
outln ( " out_val = dpix_val;");
else
outln ( " out_val = colors_for_drawing.acolors[0];");
if (hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && bpp == DEPTH_16BPP && spr == 0) {
out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr);
@ -353,14 +366,14 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
outln ( " dpix += 2;");
} else if (bpp == DEPTH_16BPP) {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 2);
out_sprite (bpp, hmode, cmode, aga, 2, spr);
} else {
outln ( " *((uae_u32 *)&buf[dpix]) = out_val;");
outln ( " dpix += 2;");
}
} else {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 2);
out_sprite (bpp, hmode, cmode, aga, 2, spr);
} else {
put_dpix ("out_val");
put_dpix ("out_val");
@ -372,7 +385,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
outln ( " dpix += 4;");
} else if (bpp == DEPTH_16BPP) {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 4);
out_sprite (bpp, hmode, cmode, aga, 4, spr);
} else {
outln ( " *((uae_u32 *)&buf[dpix]) = out_val;");
outln ( " dpix += 2;");
@ -381,7 +394,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
}
} else {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 4);
out_sprite (bpp, hmode, cmode, aga, 4, spr);
} else {
put_dpix ("out_val");
put_dpix ("out_val");
@ -392,14 +405,14 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
} else {
if (bpp == DEPTH_16BPP) {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 1);
out_sprite (bpp, hmode, cmode, aga, 1, spr);
} else {
outln ( " *((uae_u32 *)&buf[dpix]) = out_val;");
outln ( " dpix += 2;");
}
} else {
if (spr) {
out_sprite (bpp, hmode, cmode, aga, 1);
out_sprite (bpp, hmode, cmode, aga, 1, spr);
} else {
put_dpix ("out_val");
}
@ -438,18 +451,23 @@ static void out_linetoscr (DEPTH_T bpp, HMODE_T hmode, int aga, int spr)
outlnf ( " %s *buf = (%s *) xlinebuffer;", get_depth_type_str (bpp), get_depth_type_str (bpp));
if (spr)
outln ( " uae_u8 sprcol;");
if (aga)
if (aga && spr >= 0)
outln ( " uae_u8 xor_val = bplxor;");
outln ( "");
outln ( " if (bplham) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_HAM);
outln ( " } else if (bpldualpf) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_DUALPF);
outln ( " } else if (bplehb) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_EXTRAHB);
outln ( " } else {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
if (spr >= 0) {
outln ( " if (bplham) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_HAM);
outln ( " } else if (bpldualpf) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_DUALPF);
outln ( " } else if (bplehb) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_EXTRAHB);
outln ( " } else {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
} else {
outln ( " if (1) {");
out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_NORMAL);
}
outln ( " }\n");
outln ( " return spix;");
@ -479,7 +497,7 @@ int main (int argc, char *argv[])
set_outfile (stdout);
outln ("/*");
outln (" * E-UAE - The portable Amiga emulator.");
outln (" * UAE - The portable Amiga emulator.");
outln (" *");
outln (" * This file was generated by genlinetoscr. Don't edit.");
outln (" */");
@ -489,7 +507,9 @@ int main (int argc, char *argv[])
for (aga = 0; aga <= 1 ; aga++) {
if (aga && bpp == DEPTH_8BPP)
continue;
for (spr = 0; spr <= 1; spr++) {
for (spr = -1; spr <= 1; spr++) {
if (!aga && spr < 0)
continue;
for (hmode = HMODE_NORMAL; hmode <= HMODE_MAX; hmode++)
out_linetoscr (bpp, hmode, aga, spr);
}

View File

@ -11,9 +11,9 @@
#define MEMLOGR 0
#define MEMLOGW 0
#define MEMLOGINDIRECT 0
#define MEMDEBUG 0
#define MEMDEBUG 1
#define MEMDEBUGMASK 0x7fffff
#define MEMDEBUGTEST 0x280000
#define MEMDEBUGTEST 0x1ff000
#define PICASSOIV_DEBUG_IO 0
static bool memlogr = false;
@ -102,6 +102,9 @@ struct gfxboard
#define ISP4() (currprefs.rtgmem_type == PICASSOIV_Z2 || currprefs.rtgmem_type == PICASSOIV_Z3)
// Picasso II: 8* 4x256 (1M) or 16* 4x256 (2M)
// Piccolo: 8* 4x256 + 2* 16x256 (2M)
static struct gfxboard boards[] =
{
{

View File

@ -1,3 +1,7 @@
#ifndef A2091_H
#define A2091_H
#ifdef A2091
extern addrbank dmaca2091_bank;
@ -35,3 +39,5 @@ extern int add_scsi_cd (int ch, int unitnum);
extern int add_scsi_tape (int ch, const TCHAR *tape_directory, bool readonly);
#endif
#endif /* A2091H */

View File

@ -1,4 +1,7 @@
#ifndef BLKDEV_H
#define BLKDEV_H
#define DEVICE_SCSI_BUFSIZE (65536 - 1024)
#define SCSI_UNIT_DISABLED -1
@ -210,3 +213,5 @@ extern void blkdev_entergui (void);
extern void blkdev_exitgui (void);
bool filesys_do_disk_change (int, bool);
#endif /* BLKDEV_H */

View File

@ -6,6 +6,9 @@
* (c) 1995 Bernd Schmidt
*/
#ifndef CUSTOM_H
#define CUSTOM_H
#include "machdep/rpt.h"
/* These are the masks that are ORed together in the chipset_mask option.
@ -85,7 +88,7 @@ extern unsigned int joy0dir, joy1dir;
extern int joy0button, joy1button;
extern void INTREQ (uae_u16);
extern void INTREQ_0 (uae_u16);
extern bool INTREQ_0 (uae_u16);
extern void INTREQ_f (uae_u16);
extern void send_interrupt (int num, int delay);
extern uae_u16 INTREQR (void);
@ -231,3 +234,5 @@ extern bool ispal (void);
extern int current_maxvpos (void);
extern struct chipset_refresh *get_chipset_refresh (void);
extern void compute_framesync (void);
#endif /* CUSTOM_H */

View File

@ -110,9 +110,20 @@ STATIC_INLINE void set_cycles (unsigned long int x)
#endif
}
STATIC_INLINE int current_hpos_safe (void)
{
int hp = (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
return hp;
}
STATIC_INLINE int current_hpos (void)
{
return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
int hp = current_hpos_safe ();
if (hp < 0 || hp >= 256) {
gui_message(_T("hpos = %d!?\n"), hp);
hp = 0;
}
return hp;
}
STATIC_INLINE bool cycles_in_range (unsigned long endcycles)

View File

@ -6,6 +6,9 @@
* Copyright 1997 Bernd Schmidt
*/
#ifndef FILESYS_H
#define FILESYS_H
struct hardfilehandle;
#define MAX_HDF_CACHE_BLOCKS 128
@ -146,3 +149,4 @@ extern void getchsgeometry (uae_u64 size, int *pcyl, int *phead, int *psectorspe
extern void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int *phead, int *psectorspertrack);
extern void getchspgeometry (uae_u64 total, int *pcyl, int *phead, int *psectorspertrack, bool idegeometry);
#endif /* MEMORY_H */

View File

@ -6,6 +6,9 @@
* Copyright 1995 Bernd Schmidt
*/
#ifndef MEMORY_H
#define MEMORY_H
extern void memory_reset (void);
extern void a1000_reset (void);
@ -440,3 +443,5 @@ extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
extern uae_s32 getz2size (struct uae_prefs *p);
extern ULONG getz2endaddr (void);
#endif /* MEMORY_H */

View File

@ -7,6 +7,9 @@
* Copyright 1995-2001 Bernd Schmidt
*/
#ifndef OPTIONS_H
#define OPTIONS_H
#define UAEMAJOR 2
#define UAEMINOR 7
#define UAESUBREV 1
@ -30,7 +33,7 @@ struct strlist {
#define MAX_TOTAL_SCSI_DEVICES 8
/* maximum number native input devices supported (single type) */
#define MAX_INPUT_DEVICES 16
#define MAX_INPUT_DEVICES 20
/* maximum number of native input device's buttons and axles supported */
#define MAX_INPUT_DEVICE_EVENTS 256
/* 4 different customization settings */
@ -664,3 +667,5 @@ extern struct uae_prefs currprefs, changed_prefs;
extern int machdep_init (void);
extern void machdep_free (void);
#endif /* OPTIONS_H */

View File

@ -108,4 +108,4 @@ extern void tape_media_change (int unitnum, struct uaedev_config_info*);
#define SCSI_STATUS_RESERVATION_CONFLICT 0x18
#define SCSI_STATUS_COMMAND_TERMINATED 0x22
#define SCSI_STATUS_QUEUE_FULL 0x28
#define SCSI_STATUS_ACA_ACTIVE 0x30
#define SCSI_STATUS_ACA_ACTIVE 0x30

49
include/uaenative.h Normal file
View File

@ -0,0 +1,49 @@
/*
* UAE - The Un*x Amiga Emulator
*
* UAE Native Interface (UNI)
*
* Copyright 2013-2014 Frode Solheim
*/
#ifndef _UAE_UAENATIVE_H_
#define _UAE_UAENATIVE_H_
#ifdef WITH_UAENATIVE
#if defined(_WIN32) || defined(WINDOWS)
#define UNIAPI __declspec(dllimport)
#define UNICALL __cdecl
#else // _WIN32 not defined
#define UNIAPI
#define UNICALL
#endif
#include "uni_common.h"
#define UNI_FLAG_ASYNCHRONOUS 1
#define UNI_FLAG_COMPAT 2
#define UNI_FLAG_NAMED_FUNCTION 4
uae_u32 uaenative_open_library(TrapContext *context, int flags);
uae_u32 uaenative_get_function(TrapContext *context, int flags);
uae_u32 uaenative_call_function(TrapContext *context, int flags);
uae_u32 uaenative_close_library(TrapContext *context, int flags);
void *uaenative_get_uaevar(void);
void uaenative_install ();
uaecptr uaenative_startup (uaecptr resaddr);
/* This function must return a list of directories to look for native
* libraries in. The returned list must be NULL-terminated, and must not
* be de-allocated. */
const TCHAR **uaenative_get_library_dirs(void);
#endif // WITH_UAENATIVE
#endif // _UAE_UAENATIVE_H_

80
include/uni_common.h Normal file
View File

@ -0,0 +1,80 @@
/*
* UAE - The Un*x Amiga Emulator
*
* UAE Native Interface (UNI)
*
* Copyright 2013-2014 Frode Solheim
*/
#ifndef _UAE_UNI_COMMON_H_
#define _UAE_UNI_COMMON_H_
#define UNI_VERSION 1
#ifndef UNI_MIN_VERSION
// MIN_UNI_VERSION decides which callback functions are declared available.
// The default, unless overriden is to required the current UNI version.
#define UNI_MIN_VERSION UNI_VERSION
#endif
#define UNI_ERROR_NOT_ENABLED 0x70000001
#define UNI_ERROR_INVALID_LIBRARY 0x70000002
#define UNI_ERROR_INVALID_FUNCTION 0x70000002
#define UNI_ERROR_FUNCTION_NOT_FOUND 0x70000003
#define UNI_ERROR_LIBRARY_NOT_FOUND 0x70000004
#define UNI_ERROR_INVALID_FLAGS 0x70000005
#define UNI_ERROR_COULD_NOT_OPEN_LIBRARY 0x70000006
#define UNI_ERROR_ILLEGAL_LIBRARY_NAME 0x70000007
#define UNI_ERROR_LIBRARY_TOO_OLD 0x70000008
#define UNI_ERROR_INIT_FAILED 0x70000009
#define UNI_ERROR_INTERFACE_TOO_OLD 0x7000000a
// these errors are only return from the Amiga-side uni wrappers
#define UNI_ERROR_AMIGALIB_NOT_OPEN 0x71000000
// On all current platforms, char, short and int short be 1, 2 and 4 bytes
// respectively, so we just use these simple types.
typedef char uni_char;
typedef unsigned char uni_uchar;
typedef short uni_short;
typedef unsigned short uni_ushort;
typedef int uni_long;
typedef unsigned int uni_ulong;
typedef int (UNICALL *uni_version_function)();
typedef void * (UNICALL *uni_resolve_function)(uni_ulong ptr);
typedef const uni_char * (UNICALL *uni_uae_version_function)(void);
struct uni {
uni_long d1;
uni_long d2;
uni_long d3;
uni_long d4;
uni_long d5;
uni_long d6;
uni_long d7;
uni_long a1;
uni_long a2;
uni_long a3;
uni_long a4;
uni_long a5;
uni_long a7;
#if UNI_VERSION >= 2
// add new struct entries for version 2 here
#endif
#ifdef CPUEMU_0 // UAE
uni_long result;
uni_long error;
uni_ulong function;
uni_ulong library;
void *native_function;
void *uaevar_compat;
int flags;
uaecptr task;
#endif
};
#endif // _UAE_UNI_COMMON_H_

View File

@ -56,6 +56,7 @@
#include "gayle.h"
#include "gfxboard.h"
#include "luascript.h"
#include "uaenative.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
@ -1004,6 +1005,9 @@ void virtualdevice_init (void)
#if defined (BSDSOCKET)
bsdlib_install ();
#endif
#ifdef WITH_UAENATIVE
uaenative_install ();
#endif
}
static int real_main2 (int argc, TCHAR **argv)

View File

@ -1266,27 +1266,27 @@ static int patch_residents (uae_u8 *kickmemory, int size)
// "scsi.device", "carddisk.device", "card.resource" };
uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000;
if (currprefs.cs_mbdmac == 2)
residents[0] = NULL;
for (i = 0; i < size - 100; i++) {
if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
uaecptr addr;
addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
if (addr != i + base)
continue;
addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
if (addr >= base && addr < base + size) {
j = 0;
while (residents[j]) {
if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
TCHAR *s = au (residents[j]);
write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base);
xfree (s);
kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
patched++;
break;
if (currprefs.cs_mbdmac != 2) {
for (i = 0; i < size - 100; i++) {
if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
uaecptr addr;
addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
if (addr != i + base)
continue;
addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
if (addr >= base && addr < base + size) {
j = 0;
while (residents[j]) {
if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
TCHAR *s = au (residents[j]);
write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base);
xfree (s);
kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
patched++;
break;
}
j++;
}
j++;
}
}
}

View File

@ -986,7 +986,7 @@ static void sortobjects (struct didata *did)
#define RDP_DEVICE1 _T("\\??\\Root#")
#define RDP_DEVICE2 _T("\\\\?\\Root#")
static int rdpdevice(TCHAR *buf)
static int rdpdevice(const TCHAR *buf)
{
if (!_tcsncmp (RDP_DEVICE1, buf, _tcslen (RDP_DEVICE1)))
return 1;
@ -1392,11 +1392,11 @@ static void dumphidbuttoncaps (PHIDP_BUTTON_CAPS pcaps, int size)
}
}
static void dumphidcaps (struct didata *did)
static void dumphidcaps (struct didata *did, int cnt)
{
HIDP_CAPS caps = did->hidcaps;
write_log (_T("\n******** USB HID: '%s'\n"), did->name);
write_log (_T("\n******** %d USB HID: '%s'\n"), cnt, did->name);
write_log (_T("Usage: %04x\n"), caps.Usage);
write_log (_T("UsagePage: %04x\n"), caps.UsagePage);
write_log (_T("InputReportByteLength: %u\n"), caps.InputReportByteLength);
@ -1500,7 +1500,7 @@ static bool initialize_rawinput (void)
if (MAX_RAW_KEYBOARD > 0 && rnum_kb > MAX_RAW_KEYBOARD)
rnum_kb = MAX_RAW_KEYBOARD;
write_log (_T("HID device check:\n"));
for (int rawcnt = 0; rawcnt < gotnum; rawcnt++) {
HANDLE h = ridl[rawcnt].hDevice;
int type = ridl[rawcnt].dwType;
@ -1533,28 +1533,44 @@ static bool initialize_rawinput (void)
} else
continue;
if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1)
if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1) {
write_log (_T("%p RIDI_DEVICENAME failed\n"), h);
continue;
if (vtmp >= bufsize)
}
if (vtmp >= bufsize) {
write_log (_T("%p RIDI_DEVICENAME too big %d\n"), h, vtmp);
continue;
if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, buf1, &vtmp) == -1)
}
if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, buf1, &vtmp) == -1) {
write_log (_T("%p RIDI_DEVICENAME %d failed\n"), h, vtmp);
continue;
}
rdi = (PRID_DEVICE_INFO)buf2;
memset (rdi, 0, sizeof (RID_DEVICE_INFO));
rdi->cbSize = sizeof (RID_DEVICE_INFO);
if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, NULL, &vtmp) == -1)
if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, NULL, &vtmp) == -1) {
write_log (_T("%p RIDI_DEVICEINFO failed\n"), h);
continue;
if (vtmp >= bufsize)
}
if (vtmp >= bufsize) {
write_log (_T("%p RIDI_DEVICEINFO too big %d\n"), h, vtmp);
continue;
if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, buf2, &vtmp) == -1)
}
if (GetRawInputDeviceInfo (h, RIDI_DEVICEINFO, buf2, &vtmp) == -1) {
write_log (_T("%p RIDI_DEVICEINFO %d failed\n"), h, vtmp);
continue;
}
write_log (_T("%p %04x/%04x (%d/%d)\n"), h, rdi->hid.dwVendorId, rdi->hid.dwProductId, rdi->hid.usUsage, rdi->hid.usUsagePage);
if (type == RIM_TYPEMOUSE) {
if (rdpdevice (buf1))
continue;
if (num_mouse >= MAX_INPUT_DEVICES - 1) /* leave space for Windows mouse */
if (num_mouse >= MAX_INPUT_DEVICES - 1) {/* leave space for Windows mouse */
write_log (_T("Too many mice\n"));
continue;
}
did += num_mouse;
num_mouse++;
rmouse++;
@ -1562,8 +1578,10 @@ static bool initialize_rawinput (void)
} else if (type == RIM_TYPEKEYBOARD) {
if (rdpdevice (buf1))
continue;
if (num_keyboard >= MAX_INPUT_DEVICES)
if (num_keyboard >= MAX_INPUT_DEVICES) {
write_log (_T("Too many keyboards\n"));
continue;
}
did += num_keyboard;
num_keyboard++;
rkb++;
@ -1571,16 +1589,26 @@ static bool initialize_rawinput (void)
} else if (type == RIM_TYPEHID) {
if (rdpdevice (buf1))
continue;
if (rdi->hid.usUsage != 4 && rdi->hid.usUsage != 5)
if (rdi->hid.usUsage != 4 && rdi->hid.usUsage != 5) {
write_log (_T("RAWHID: Usage not 4 or 5 (%d)\n"), rdi->hid.usUsage);
continue;
if (rdi->hid.usUsagePage >= 0xff00) // vendor specific
}
if (rdi->hid.usUsagePage >= 0xff00) { // vendor specific
write_log (_T("RAWHID: Ignored vendor specific %04x\n"), rdi->hid.usUsagePage);
continue;
}
for (i = 0; hidnorawinput[i].vid; i++) {
if (rdi->hid.dwProductId == hidnorawinput[i].pid && rdi->hid.dwVendorId == hidnorawinput[i].vid)
break;
}
if (hidnorawinput[i].vid || num_joystick >= MAX_INPUT_DEVICES)
if (hidnorawinput[i].vid) {
write_log (_T("RAWHID: blacklisted\n"));
continue;
}
if (num_joystick >= MAX_INPUT_DEVICES) {
write_log (_T("RAWHID: too many devices\n"));
continue;
}
did += num_joystick;
num_joystick++;
rhid++;
@ -1675,7 +1703,7 @@ static bool initialize_rawinput (void)
if (HidP_GetCaps (did->hidpreparseddata, &did->hidcaps) == HIDP_STATUS_SUCCESS) {
PHIDP_BUTTON_CAPS bcaps;
USHORT size = did->hidcaps.NumberInputButtonCaps;
dumphidcaps (did);
dumphidcaps (did, rawcnt);
bcaps = xmalloc (HIDP_BUTTON_CAPS, size);
if (HidP_GetButtonCaps (HidP_Input, bcaps, &size, did->hidpreparseddata) == HIDP_STATUS_SUCCESS) {
dumphidbuttoncaps (bcaps, size);
@ -3164,6 +3192,14 @@ static void release_keys (void)
rawprevkey = -1;
}
static void flushmsgpump (void)
{
MSG msg;
while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
static int acquire_kb (int num, int flags)
{
@ -3172,6 +3208,7 @@ static int acquire_kb (int num, int flags)
if (num < 0) {
doregister_rawinput ();
if (currprefs.keyboard_leds_in_use) {
//write_log (_T("***********************acquire_kb_led\n"));
if (!currprefs.win32_kbledmode) {
if (DefineDosDevice (DDD_RAW_TARGET_PATH, _T("Kbd"), _T("\\Device\\KeyboardClass0"))) {
kbhandle = CreateFile (_T("\\\\.\\Kbd"), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
@ -3189,7 +3226,8 @@ static int acquire_kb (int num, int flags)
originalleds = oldleds;
//write_log (_T("stored %08x -> %08x\n"), originalleds, newleds);
}
update_leds ();
set_leds (newleds);
flushmsgpump ();
}
return 1;
}
@ -3219,10 +3257,12 @@ static void unacquire_kb (int num)
if (num < 0) {
doregister_rawinput ();
if (currprefs.keyboard_leds_in_use) {
//write_log (_T("*********************** unacquire_kb_led\n"));
if (originalleds != -1) {
//write_log (_T("restored %08x -> %08x\n"), oldleds, originalleds);
set_leds (originalleds);
originalleds = -1;
flushmsgpump ();
}
if (kbhandle != INVALID_HANDLE_VALUE) {
CloseHandle (kbhandle);

View File

@ -75,9 +75,24 @@ struct uae_driveinfo {
* - block 0 is zeroed
*/
int harddrive_dangerous, do_rdbdump;
int harddrive_dangerous = 0x1234dead;
int do_rdbdump;
static struct uae_driveinfo uae_drives[MAX_FILESYSTEM_UNITS];
#if 0
static void fixdrive (struct hardfiledata *hfd)
{
uae_u8 data[512];
struct zfile *zf = zfile_fopen (_T("d:\\amiga\\hdf\\a500supradrive.hdf"), _T("rb"));
for (int i = 0; i < 0x30000 / 512; i++) {
zfile_fread (data, 1, 512, zf);
hdf_write (hfd, data, i * 512, 512);
}
zfile_fclose (zf);
}
#endif
static int isnomediaerr (DWORD err)
{
if (err == ERROR_NOT_READY ||
@ -624,6 +639,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
goto end;
if (!DeviceIoControl (h, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &r, NULL))
write_log (_T("WARNING: '%s' FSCTL_ALLOW_EXTENDED_DASD_IO returned %d\n"), name, GetLastError ());
//queryidentifydevice (hfd);
_tcsncpy (hfd->vendor_id, udi->vendor_id, 8);
_tcsncpy (hfd->product_id, udi->product_id, 16);
@ -672,6 +688,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
}
hfd->handle_valid = HDF_HANDLE_WIN32;
hfd->emptyname = my_strdup (name);
//fixdrive (hfd);
} else {
hfd->flags = HFD_FLAGS_REALDRIVE;
hfd->drive_empty = -1;

View File

@ -16,6 +16,7 @@
#define __i386__
#define WINDOWS
#define ZLIB_WINAPI
#define PACKAGE_STRING "WinUAE"
#ifndef UAE_MINI
@ -77,6 +78,7 @@
#define RETROPLATFORM /* Cloanto RetroPlayer support */
#define WITH_CHD
#define WITH_LUA /* lua scripting */
#define WITH_UAENATIVE
#else

View File

@ -6210,6 +6210,40 @@ void fpux_restore (int *v)
#endif
}
struct winuae //this struct is put in a6 if you call
//execute native function
{
HWND amigawnd; //adress of amiga Window Windows Handle
unsigned int changenum; //number to detect screen close/open
unsigned int z3offset; //the offset to add to acsess Z3 mem from Dll side
};
void *uaenative_get_uaevar (void)
{
static struct winuae uaevar;
#ifdef _WIN32
uaevar.amigawnd = hAmigaWnd;
#endif
uaevar.z3offset = (uae_u32)get_real_address (0x10000000) - 0x10000000;
return &uaevar;
}
const TCHAR **uaenative_get_library_dirs (void)
{
static const TCHAR **nats;
static TCHAR *path;
if (nats == NULL)
nats = xcalloc (const TCHAR*, 3);
if (path == NULL) {
path = xcalloc (TCHAR, MAX_DPATH);
_tcscpy (path, start_path_data);
_tcscat (path, _T("plugins"));
}
nats[0] = start_path_data;
nats[1] = path;
return nats;
}
typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);

View File

@ -19,11 +19,11 @@
#define LANG_DLL 1
#if WINUAEPUBLICBETA
#define WINUAEBETA _T("4")
#define WINUAEBETA _T("5")
#else
#define WINUAEBETA _T("")
#endif
#define WINUAEDATE MAKEBD(2014, 1, 18)
#define WINUAEDATE MAKEBD(2014, 2, 2)
#define WINUAEEXTRA _T("")
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
VisualStudioVersion = 12.0.30110.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winuae", "winuae_msvc.vcxproj", "{4ADAA943-1AC8-4FB5-82E5-4FB753B6C2DA}"
EndProject
@ -397,7 +397,6 @@ Global
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|Mixed Platforms.Build.0 = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|Win32.ActiveCfg = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|Win32.Build.0 = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|x64.ActiveCfg = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|x86.ActiveCfg = Debug|x86
{BE211CE1-3955-4674-A664-5038FC791980}.Debug|x86.Build.0 = Debug|x86

View File

@ -204,7 +204,7 @@
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>StdCall</CallingConvention>
<CallingConvention>FastCall</CallingConvention>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<EnablePREfast>false</EnablePREfast>
@ -224,7 +224,7 @@
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;wintab32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/winuae.pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
@ -799,6 +799,7 @@
<ClCompile Include="..\..\isofs.cpp" />
<ClCompile Include="..\..\luascript.cpp" />
<ClCompile Include="..\..\qemuvga\cirrus_vga.cpp" />
<ClCompile Include="..\..\qemuvga\lsi53c895a.cpp" />
<ClCompile Include="..\..\qemuvga\qemuuaeglue.cpp" />
<ClCompile Include="..\..\qemuvga\vga.cpp" />
<ClCompile Include="..\..\scsitape.cpp" />
@ -822,6 +823,7 @@
<ClCompile Include="..\..\slirp\udp.cpp" />
<ClCompile Include="..\..\specialmonitors.cpp" />
<ClCompile Include="..\..\statusline.cpp" />
<ClCompile Include="..\..\uaenative.cpp" />
<ClCompile Include="..\ahidsound_dsonly.cpp" />
<ClCompile Include="..\ahidsound_new.cpp" />
<ClCompile Include="..\avioutput.cpp" />

View File

@ -628,6 +628,12 @@
<ClCompile Include="..\..\cpuemu_13.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\uaenative.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\qemuvga\lsi53c895a.cpp">
<Filter>qemu</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">

View File

@ -1,6 +1,66 @@
1 -> 0: 0,1FE,1FE,1FE,..
1 -> 1: 0,1FE,0,1FE,0,..
1 -> 2: 0,1FE,70,1FE,70,.. (C-)
1 -> 9: 0,1FE,0,74,0,74,.. (DA)
1 -> B: 0,1FE,70,0,74,70,0,74,70,0,74,.. (ACD)
1 -> C: 0,1FE,72,74,70,72,74,70,72,.. (CBA)
1 -> D: 0,1FE,72,74,70,72,74,70,72,.. (CBA)
1 -> E: 0,1FE,70,70,70,70,.. (C)
1 -> F: 0,1FE,70,70,74,70,70,70,74,70,70,70,74,.. (CCCA)
- restore only single input target to default.
- More than one horizontal DDFSTRT-DDFSTOP window is now accurately emulated without requiring any hacks.
Random garbage between display windows is also gone. (Subtle Shades / Nuance)
- Removed some more obsolete variables from display emulation.
- Saigon Megademo fix got accidentally broken in b2.
- 260b17 "strange right edge overscan display shift" optional hack removed, new delay/shift register
behavior creates identical output automatically simply by reseting delay counter (hpos counter) at the
end of scanline. NOTE: Some programs with large overscan can now have small graphics corruption in right
border (gap in graphics), it is not a bug, it is accurate emulation. (For example Back in Bizness / 2000AD)
- Some OCS only programs may now have graphics corruption in ECS mode (if bitplane DMA crosses scanlines),
this is also not a bug, real hardware would show even worse corruption. Someday this will be more accurately emulated.
- Agnus vpos counter increase delayed by 1 cycle. Fixes Hit the Road / Flash Production "Floffy2" part.
- Keyboard leds as power/floppy/etc indicators are now properly restored back to original state when
keyboard input is not active, changing led config on the fly also works now.
- Exiting GUI with close button or ALT-F4 didn't save GUI position.
Beta 3:
- Sprites near left border had strange corruption (b1)
- "toscr_nbits > 16" error in some situations (b1)
- "Modified interrupt delays" b1 change was bad, sometimes interrupt request was kept active
causing spurious interrupts (which caused crashes).
- New autoresolution selection was not loaded correctly from config file.
- Blitter final D write don't increase "nasty" count. (Which makes sense, blit is already
finished, blitbusy bit was cleared 2 cycles ago)
- Removed most BPLxDAT related hacks, they become obsolete after b2 BPLCON1 update (it also changed
how data gets moved to shift registers). May introduce new glitches and if it does, it needs
correct emulation updates, not hacks.
Beta 2:
- BPLCON1 mid scan line modifications now should match real hardware 100%.
This was very big change, old emulation was functionally close enough but very far from real
hardware behavior. Old code couldn't emulate some side-effects correctly.
- Partial/full scanline based mode ("SPEEDUP") is again used more regularly, "is it safe to use" check
got partially broken during 2.7.0 betas. It is also more optimal in AGA 32/64-bit fetch modes.
- AGA border sprite in right border and 2x or 4x horizontal sprite pixels (vs bitplane pixels): sprite's
rightmost pixel(s) were missing.
- Superhires and top or bottom border sprite: graphics garbage was seen in border area, memory
corruption was also possible in some situations.
- Magic mouse + mousehack mode now always stops keyboard input when mouse is outside of emulation
window, even if window still has focus.
- 68020/030 CAAR register preserves also all reserved bits.
- Disable JIT if config has 68000/010 CPU and non-zero JIT cache size.
- 68020 CE broke interrupt state fetch, interrupt didn't clear if write to INTREQ was immediately
followed by RTE. (b1)
- Does not anymore require SSE2 capable CPU (b1 did)
Beta 1:
Lots of small blitter, copper and CPU timing adjustments. (Thanks to amilo3438 for collecting huge amounts
of demo test cases). Lots of logic analyzer tests done during last few weeks.

View File

@ -417,7 +417,7 @@ static TCHAR *writets (void)
_stprintf (p, _T("%03d"), tb.millitm);
p += _tcslen (p);
if (vsync_counter != 0xffffffff)
_stprintf (p, _T(" [%d %03d%s%03d]"), vsync_counter, current_hpos (), lof_store ? _T("-") : _T("="), vpos);
_stprintf (p, _T(" [%d %03d%s%03d]"), vsync_counter, current_hpos_safe (), lof_store ? _T("-") : _T("="), vpos);
_tcscat (p, _T(": "));
return out;
}
@ -498,6 +498,9 @@ void write_log (const TCHAR *format, ...)
premsg ();
if (!_tcsicmp (format, _T("*")))
count = 0;
EnterCriticalSection (&cs);
va_start (parms, format);
bufp = buffer;

View File

@ -11,8 +11,8 @@
*
*/
#ifndef MEMORY_H
#define MEMORY_H
#ifndef QMEMORY_H
#define QMEMORY_H
#ifndef CONFIG_USER_ONLY
@ -899,4 +899,5 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
#endif
#endif
#endif /* QMEMORY */

851
uaenative.cpp Normal file
View File

@ -0,0 +1,851 @@
/*
* UAE - The Un*x Amiga Emulator
*
* UAE Native Interface (UNI) - uaenative.library
*
* Copyright 2013-2014 Frode Solheim. Amiga-side library sample code
* provided by Toni Wilen.
*
* TODO: Handling UAE reset and shutdown better. When resetting the Amiga,
* all opened native libraries should be closed, and all async call threads
* should be stopped.
*/
#include "sysconfig.h"
#include "sysdeps.h"
#ifdef WITH_UAENATIVE
#include <stdlib.h>
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "traps.h"
#include "autoconf.h"
#include "execlib.h"
#include "threaddep/thread.h"
#include "native2amiga.h"
#include "events.h"
#include "uaenative.h"
#include "fsdb.h"
#if defined(FSUAE) && defined(WINDOWS)
#define _WIN32
#endif
#ifndef _WIN32
#include <dlfcn.h>
#endif
static double syncdivisor;
#define SIGBIT 8 // SIGB_DOS
// the function prototype for the callable native functions
typedef uae_s32 (UNICALL *uae_uni_native_function)(struct uni *uni);
// the function prototype for the callable native functions (old style)
typedef uae_u32 (UNICALL *uae_uni_native_compat_function)(uae_u32, uae_u32,
uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32,
uae_u32, uae_u32, uae_u32, void *, uae_u32, void *);
// the function prototype for the native library's uni_init function
typedef int (UNICALL *uni_init_function)(void);
struct library_data {
void *dl_handle;
uae_thread_id thread_id;
uae_sem_t empty_count;
uae_sem_t full_count;
int thread_stop_flag;
struct uni *uni;
};
struct uni_handle {
struct library_data *library;
void *function;
};
static uni_handle *g_handles = NULL;
static int g_allocated_handles = 0;
static int g_max_handle = -1;
#if defined (_WIN32)
#define OS_EXTENSION _T("-windows")
#define FILE_EXTENSION _T(".dll")
#elif defined (LINUX)
#define OS_EXTENSION _T("-linux")
#define FILE_EXTENSION _T(".so")
#elif defined (MACOSX)
#define OS_EXTENSION _T("-macosx")
#define FILE_EXTENSION _T(".dylib")
#elif defined (FREEBSD)
#define OS_EXTENSION _T("-freebsd")
#define FILE_EXTENSION _T(".so")
#elif defined (OPENBSD)
#define OS_EXTENSION _T("-openbsd")
#define FILE_EXTENSION _T(".so")
#else
#define OS_EXTENSION _T("-unknown")
#define FILE_EXTENSION _T(".unknown")
#endif
#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
#define ARCH_EXTENSION _T("-x86-64")
#elif defined(__i386__) || defined (_M_IX86)
#define ARCH_EXTENSION _T("-x86")
#elif defined(__ppc__)
#define ARCH_EXTENSION _T("-ppc")
#else
#define ARCH_EXTENSION _T("-unknown")
#endif
static int UNICALL uni_version(void)
{
return UNI_VERSION;
}
static void * UNICALL uni_resolve(uae_u32 ptr)
{
void *result = get_real_address (ptr);
//printf ("UNI: resolve address 0x%08x -> %p\n", ptr, result);
return result;
}
static const char * UNICALL uni_uae_version(void)
{
// A standard GNU macro with a string containing program name and
// version, e.g. "WinUAE 2.7.0" or "FS-UAE 2.3.16dev".
return PACKAGE_STRING;
}
static void free_library_data(struct library_data *library_data) {
if (library_data->empty_count) {
uae_sem_destroy(&library_data->empty_count);
}
if (library_data->full_count) {
uae_sem_destroy(&library_data->full_count);
}
free(library_data);
}
static uae_u32 register_handle(library_data *library_data, void *function)
{
int index = -1;
if (g_max_handle >= g_allocated_handles - 1) {
// Entries above g_max_handle are assumed to be uninitialized,
// but unused/"freed" entries below g_max_handle must be zeroed.
// Try to find a reusable entry before allocating more space.
for (int i = 0; i < g_max_handle; i++) {
if (g_handles[i].library == NULL && g_handles[i].function == NULL) {
index = i;
break;
}
}
if (index == -1) {
int new_count = g_allocated_handles * 2;
if (new_count == 0) {
new_count = 128;
}
write_log("uni: allocating memory for %d handles\n", new_count);
g_handles = (uni_handle *) realloc(g_handles,
new_count * sizeof(struct uni_handle));
g_allocated_handles = new_count;
}
}
if (index == -1) {
index = g_max_handle + 1;
g_max_handle = index;
}
g_handles[index].library = library_data;
g_handles[index].function = function;
// valid handles start from 0x80000000, anything below is error code
return (uae_u32) 0x80000000 + (uae_u32) index;
}
static TCHAR *get_native_library_path (const TCHAR *library_name)
{
write_log (_T("uni: find_native_library %s\n"), library_name);
TCHAR path[PATH_MAX];
const TCHAR **library_dirs = uaenative_get_library_dirs ();
for (const TCHAR **dir = library_dirs; *dir != NULL; dir++) {
// name must already have been checked to not contain anything
// to allow access to parent directories.
_sntprintf (path, PATH_MAX, _T("%s%s%s"), *dir, library_name,
OS_EXTENSION ARCH_EXTENSION FILE_EXTENSION);
write_log (_T("uni: checking %s\n"), path);
if (my_existsfile (path)) {
return my_strdup (path);
}
#ifdef _WIN32
// for compatibility with existing WinUAE native interface
_sntprintf (path, PATH_MAX, _T("%s%s.dll"), *dir, library_name);
write_log (_T("uni: checking %s\n"), path);
if (my_existsfile (path)) {
return my_strdup (path);
}
#endif
}
return NULL;
}
static void *dl_symbol(void *dl, const char *name)
{
if (dl == NULL) {
return NULL;
}
#ifdef _WIN32
return (void *) GetProcAddress ((HINSTANCE) dl, name);
#else
return dlsym (dl, name);
#endif
}
static void dl_close(void *dl)
{
#ifdef _WIN32
FreeLibrary ((HMODULE) dl);
#else
dlclose (dl);
#endif
}
static void set_library_globals(void *dl)
{
void *address;
address = dl_symbol(dl, "uni_version");
if (address) *((uni_version_function *) address) = &uni_version;
address = dl_symbol(dl, "uni_resolve");
if (address) *((uni_resolve_function *) address) = &uni_resolve;
address = dl_symbol(dl, "uni_uae_version");
if (address) *((uni_uae_version_function *) address) = &uni_uae_version;
}
static uae_u32 open_library (const char *name, uae_u32 min_version)
{
syncdivisor = (3580000.0 * CYCLE_UNIT) / (double) syncbase;
for (const char *c = name; *c; c++) {
if (*c == '/' || *c == '\\' || *c == ':') {
return UNI_ERROR_ILLEGAL_LIBRARY_NAME;
}
}
TCHAR *tname = au (name);
write_log (_T("uni: open native library '%s'\n"), tname);
TCHAR *path = get_native_library_path (tname);
free (tname);
if (path == NULL) {
write_log(_T("uni: library not found\n"));
return UNI_ERROR_LIBRARY_NOT_FOUND;
}
write_log (_T("uni: found library at %s - opening\n"), path);
#ifdef _WIN32
void *dl = LoadLibrary (path);
#else
void *dl = dlopen (path, RTLD_NOW);
#endif
free(path);
if (dl == NULL) {
write_log (_T("uni: error opening library errno %d\n"), errno);
return UNI_ERROR_COULD_NOT_OPEN_LIBRARY;
}
// FIXME: check min version
set_library_globals(dl);
void *function_address = dl_symbol(dl, "uni_init");
if (function_address) {
int error = ((uni_init_function) function_address)();
if (error) {
dl_close(dl);
return error;
}
}
struct library_data *library_data = (struct library_data *) malloc(
sizeof(struct library_data));
memset(library_data, 0, sizeof(struct library_data));
library_data->dl_handle = dl;
uae_u32 handle = register_handle (library_data, NULL);
write_log(_T("uni: opened library %08x (%p)\n"), handle, dl);
return handle;
}
uae_u32 uaenative_open_library (TrapContext *context, int flags)
{
if (!currprefs.native_code) {
write_log(_T("uni: tried to open native library, but native code ")
_T("is not enabled\n"));
return UNI_ERROR_NOT_ENABLED;
}
uaecptr name;
uae_u32 min_version;
if (flags & UNI_FLAG_COMPAT) {
name = m68k_areg (regs, 0);
min_version = 0;
}
else {
name = m68k_areg (regs, 1);
min_version = m68k_dreg (regs, 0);
}
uae_u32 result = open_library (
(const char *) get_real_address (name), min_version);
if ((flags & UNI_FLAG_COMPAT) && !(result & 0x80000000)) {
// error opening library, return 0 for error in compatibility mode
return 0;
}
return result;
}
static struct library_data *get_library_data_from_handle (uae_u32 handle)
{
int index = handle - (uae_u32) 0x80000000;
//printf("check library index %u\n", index);
if (index < 0 || index > g_max_handle) {
//printf("index < 0 || index > g_max_handle\n");
return NULL;
}
if (g_handles[index].function) {
//printf("- g_handles[index].function\n");
return NULL;
}
return g_handles[index].library;
}
static uae_u32 get_function_handle (uae_u32 handle, const char *name)
{
struct library_data *library_data = get_library_data_from_handle (handle);
if (library_data == NULL) {
write_log(_T("uni: get_function - invalid library (%d)\n"), handle);
return UNI_ERROR_INVALID_LIBRARY;
}
void *function_address = dl_symbol (library_data->dl_handle, name);
if (!function_address) {
write_log(_T("uni: get_function - function (%s) not found ")
_T("in library %d (%p)\n"), name, handle,
library_data->dl_handle);
return UNI_ERROR_FUNCTION_NOT_FOUND;
}
return register_handle (library_data, function_address);
}
uae_u32 uaenative_get_function (TrapContext *context, int flags)
{
if (!currprefs.native_code) {
return UNI_ERROR_NOT_ENABLED;
}
//m68k_dreg (regs, 1), m68k_areg (regs, 0),
//m68k_dreg (regs, 0), m68k_areg (regs, 1),
uaecptr name;
uae_u32 library;
if (flags & UNI_FLAG_COMPAT) {
name = m68k_areg (regs, 0);
library = m68k_dreg (regs, 1);
}
else {
library = m68k_areg (regs, 0);
name = m68k_areg (regs, 1);
}
uae_u32 result = get_function_handle (
library, (const char *) get_real_address (name));
if ((flags & UNI_FLAG_COMPAT) && !(result & 0x80000000)) {
// error getting function, return 0 for error in compatibility mode
return 0;
}
return result;
}
#if defined(X86_MSVC_ASSEMBLY)
static uae_u32 do_call_function_compat_asm (struct uni *uni)
{
unsigned int espstore;
void *native_func = uni->native_function;
uae_u32 d1 = uni->d1;
uae_u32 d2 = uni->d2;
uae_u32 d3 = uni->d3;
uae_u32 d4 = uni->d4;
uae_u32 d5 = uni->d5;
uae_u32 d6 = uni->d6;
uae_u32 d7 = uni->d7;
uae_u32 a1 = uni->a1;
uae_u32 a2 = uni->a2;
uae_u32 a3 = uni->a3;
uae_u32 a4 = uni->a4;
uae_u32 a5 = uni->a5;
uae_u32 a7 = uni->a7;
uae_u32 regs_ = (uae_u32)&regs;
void *a6 = uni->uaevar_compat;
__asm
{ mov espstore,esp
push regs_
push a7
push a6
push a5
push a4
push a3
push a2
push a1
push d7
push d6
push d5
push d4
push d3
push d2
push d1
call native_func
mov esp,espstore
}
}
#endif
static void do_call_function (struct uni *uni) {
printf("uni: calling native function %p\n", uni->native_function);
unsigned long start_time;
const int flags = uni->flags;
if ((flags & UNI_FLAG_ASYNCHRONOUS) == 0) {
start_time = read_processor_time ();
}
if (uni->flags & UNI_FLAG_COMPAT) {
#if defined(X86_MSVC_ASSEMBLY)
uni->result = (uae_s32) do_call_function_compat_asm(uni);
#else
uni->result = ((uae_uni_native_compat_function) uni->native_function) (
uni->d1, uni->d2, uni->d3, uni->d4, uni->d5, uni->d6,
uni->d7, uni->a1, uni->a2, uni->a3, uni->a4, uni->a5,
uni->uaevar_compat, uni->a7, &regs);
#endif
}
else {
uni->result = ((uae_uni_native_function) uni->native_function) (uni);
}
if ((flags & UNI_FLAG_ASYNCHRONOUS) == 0) {
unsigned long time_diff = read_processor_time () - start_time;
double v = syncdivisor * time_diff;
if (v > 0) {
if (v > 1000000 * CYCLE_UNIT) {
v = 1000000 * CYCLE_UNIT;
}
// compensate for the time spent in the native function
do_extra_cycles ((unsigned long) (syncdivisor * time_diff));
}
}
}
static void *uaenative_thread(void *arg)
{
struct library_data *library_data = (struct library_data *) arg;
while (1) {
uae_sem_wait(&library_data->full_count);
if (library_data->thread_stop_flag) {
break;
}
if (library_data->uni) {
do_call_function (library_data->uni);
uae_Signal (library_data->uni->task, 1 << SIGBIT);
}
library_data->uni = NULL;
uae_sem_post(&library_data->empty_count);
}
write_log (_T("uni: uaenative_thread exiting\n"));
free_library_data(library_data);
return NULL;
}
uae_u32 uaenative_call_function (TrapContext *context, int flags)
{
if (!currprefs.native_code) {
return UNI_ERROR_NOT_ENABLED;
}
struct uni uni;
uni.function = m68k_areg (regs, 0);
if (flags & UNI_FLAG_COMPAT) {
uni.library = 0;
uni.uaevar_compat = uaenative_get_uaevar();
}
else if (flags & UNI_FLAG_NAMED_FUNCTION) {
uni.library = m68k_dreg (regs, 0);
}
else {
uni.library = 0;
}
struct library_data *library_data;
if (uni.library) {
// library handle given, function is pointer to function name
const char *function = (const char *) get_real_address (uni.function);
library_data = get_library_data_from_handle (uni.library);
if (library_data == NULL) {
write_log (_T("uni: get_function - invalid library (%d)\n"),
uni.library);
return UNI_ERROR_INVALID_LIBRARY;
}
uni.native_function = dl_symbol (library_data->dl_handle, function);
if (uni.native_function == NULL) {
write_log (_T("uni: get_function - function (%s) not found ")
_T("in library %d (%p)\n"), function, uni.library,
library_data->dl_handle);
return UNI_ERROR_FUNCTION_NOT_FOUND;
}
}
else {
// library handle not given, function argument is function handle
int index = uni.function - (uae_u32) 0x80000000;
if (index >= 0 && index <= g_max_handle) {
uni.native_function = g_handles[index].function;
library_data = g_handles[index].library;
}
else {
uni.native_function = NULL;
}
if (uni.native_function == NULL) {
// printf ("UNI_ERROR_INVALID_FUNCTION\n");
return UNI_ERROR_INVALID_FUNCTION;
}
}
if (context == NULL) {
// we have no context and cannot call into m68k space
flags &= ~UNI_FLAG_ASYNCHRONOUS;
}
uni.d1 = m68k_dreg (regs, 1);
uni.d2 = m68k_dreg (regs, 2);
uni.d3 = m68k_dreg (regs, 3);
uni.d4 = m68k_dreg (regs, 4);
uni.d5 = m68k_dreg (regs, 5);
uni.d6 = m68k_dreg (regs, 6);
uni.d7 = m68k_dreg (regs, 7);
uni.a1 = m68k_areg (regs, 1);
uni.a2 = m68k_areg (regs, 2);
uni.a3 = m68k_areg (regs, 3);
uni.a4 = m68k_areg (regs, 4);
uni.a5 = m68k_areg (regs, 5);
uni.a7 = m68k_areg (regs, 7);
uni.flags = flags;
uni.error = 0;
if (flags & UNI_FLAG_ASYNCHRONOUS) {
uaecptr sysbase = get_long (4);
uni.task = get_long (sysbase + 276); // ThisTask
// make sure signal bit is cleared
m68k_dreg (regs, 0) = 0;
m68k_dreg (regs, 1) = 1 << SIGBIT;
CallLib (context, sysbase, -0x132); // SetSignal
// start thread if necessary
if (!library_data->thread_id) {
uae_sem_init (&library_data->full_count, 0, 0);
// we don't have a queue as such, the thread only processes
// one item at a time with a "queue size" of 1
uae_sem_init (&library_data->empty_count, 0, 1);
uae_start_thread (_T("uaenative"), uaenative_thread,
library_data, &library_data->thread_id);
}
// signal async thread to process new function call
uae_sem_wait(&library_data->empty_count);
library_data->uni = &uni;
uae_sem_post(&library_data->full_count);
// wait for signal
m68k_dreg (regs, 0) = 1 << SIGBIT;
CallLib (context, sysbase, -0x13e); // Wait
write_log (_T("uni: -- Got async result --\n"));
}
else {
// synchronous mode, just call the function here and now
do_call_function(&uni);
}
return uni.result;
}
uae_u32 uaenative_close_library(TrapContext *context, int flags)
{
if (!currprefs.native_code) {
return UNI_ERROR_NOT_ENABLED;
}
uae_u32 handle;
if (flags & UNI_FLAG_COMPAT) {
handle = m68k_dreg (regs, 1);
}
else {
handle = m68k_areg (regs, 1);
}
struct library_data *library_data = get_library_data_from_handle (handle);
if (library_data == NULL) {
return UNI_ERROR_INVALID_LIBRARY;
}
dl_close (library_data->dl_handle);
// We now "free" the library and function entries for this library. This
// makes the entries available for re-use. The bad thing about this is
// that it could be possible for a buggy Amiga program to call a
// mismatching function if a function handle is kept after the library
// is closed.
for (int i = 0; i <= g_max_handle; i++) {
if (g_handles[i].library == library_data) {
g_handles[i].library = NULL;
g_handles[i].function = NULL;
}
}
if (library_data->thread_id) {
write_log (_T("uni: signalling uaenative_thread to stop\n"));
library_data->thread_stop_flag = 1;
// wake up thread so it can shut down
uae_sem_post(&library_data->full_count);
}
else {
free_library_data(library_data);
}
return 0;
}
// ----------------------------------------------------------------------------
typedef uae_u32 (REGPARAM2 *uae_library_trap) (TrapContext *context);
struct uae_library_trap_def {
uae_library_trap function; // native function pointer for trap
int flags; // trap flags, e.g. TRAPFLAG_EXTRA_STACK
uaecptr aptr; // address of trap (Amiga-side)
};
struct uae_library {
// these members must be specified
const TCHAR *name;
const TCHAR *id;
int version;
int revision;
uae_library_trap_def *traps;
// these members can default to 0
int data_size;
// these members will be initialized by library functions
uaecptr aptr_name;
uaecptr aptr_id;
uaecptr aptr_init;
uaecptr aptr_func_table;
uaecptr aptr_data_table;
};
void uae_library_install (struct uae_library *library)
{
library->aptr_name = ds (library->name);
library->aptr_id = ds (library->id);
for (uae_library_trap_def *t = library->traps; t->function; t++) {
t->aptr = here ();
calltrap (deftrap2 (t->function, t->flags, _T("")));
dw (RTS);
}
library->aptr_func_table = here ();
for (uae_library_trap_def *t = library->traps + 1; t->function; t++) {
dl (t->aptr);
}
dl (0xFFFFFFFF); // end of table
library->aptr_data_table = here ();
dw (0xE000); // INITBYTE
dw (0x0008); // LN_TYPE
dw (0x0900); // NT_LIBRARY
dw (0xE000); // INITBYTE
dw (0x0009); // LN_PRI
dw (0xCE00); // -50
dw (0xC000); // INITLONG
dw (0x000A); // LN_NAME
dl (library->aptr_name);
dw (0xE000); // INITBYTE
dw (0x000E); // LIB_FLAGS
dw (0x0600); // LIBF_SUMUSED | LIBF_CHANGED
dw (0xD000); // INITWORD
dw (0x0014); // LIB_VERSION
dw (library->version);
dw (0xD000);
dw (0x0016); // LIB_REVISION
dw (library->revision);
dw (0xC000);
dw (0x0018); // LIB_IDSTRING
dl (library->aptr_id);
dl (0x00000000); // end of table
library->aptr_init = here ();
dl (SIZEOF_LIBRARY + library->data_size);
dl (library->aptr_func_table);
dl (library->aptr_data_table);
dl (library->traps[0].aptr);
write_log (_T("%s installed\n"), library->name);
}
uaecptr uae_library_startup (uaecptr res_addr, struct uae_library *library)
{
if (library->aptr_name == 0 || !currprefs.native_code) {
return res_addr;
}
put_word (res_addr + 0x00, 0x4AFC);
put_long (res_addr + 0x02, res_addr);
put_long (res_addr + 0x06, res_addr + 0x1A); // Continue scan here
put_word (res_addr + 0x0A, 0x8004); // RTF_AUTOINIT, RT_VERSION
put_word (res_addr + 0x0C, 0x0970); // NT_LIBRARY, RT_PRI
put_long (res_addr + 0x0E, library->aptr_name);
put_long (res_addr + 0x12, library->aptr_id);
put_long (res_addr + 0x16, library->aptr_init);
return res_addr + 0x1A;
}
// ----------------------------------------------------------------------------
static uae_u32 REGPARAM2 lib_init (TrapContext *context)
{
uaecptr aptr_base = m68k_dreg (regs, 0);
#if 0
uaecptr aptr_data = aptr_base + SIZEOF_LIBRARY; // sizeof(Library)
// our library data area, LIB_DATA_SIZE must be at least as big
put_long (aptr_data + 0, somedata);
#endif
return aptr_base;
}
static uae_u32 REGPARAM2 lib_open (TrapContext *context)
{
// we could do some security checks here if only some specific Amiga
// tasks can call us or something like that
put_word (m68k_areg (regs, 6) + 32,
get_word (m68k_areg (regs, 6) + 32) + 1);
return m68k_areg (regs, 6);
}
static uae_u32 REGPARAM2 lib_close (TrapContext *context)
{
put_word (m68k_areg (regs, 6) + 32,
get_word (m68k_areg (regs, 6) + 32) - 1);
return 0;
}
static uae_u32 REGPARAM2 lib_expunge (TrapContext *context)
{
return 0;
}
static uae_u32 REGPARAM2 lib_null (TrapContext *context)
{
return 0;
}
static uae_u32 REGPARAM2 lib_open_library (TrapContext *context)
{
return uaenative_open_library (context, 0);
}
static uae_u32 REGPARAM2 lib_close_library (TrapContext *context)
{
return uaenative_close_library (context, 0);
}
static uae_u32 REGPARAM2 lib_get_function (TrapContext *context)
{
return uaenative_get_function (context, 0);
}
static uae_u32 REGPARAM2 lib_call_function (TrapContext *context)
{
int flags = 0;
return uaenative_call_function (context, flags);
}
static uae_u32 REGPARAM2 lib_call_function_async (TrapContext *context)
{
int flags = UNI_FLAG_ASYNCHRONOUS;
return uaenative_call_function (context, flags);
}
static uae_u32 REGPARAM2 lib_call_function_by_name (TrapContext *context)
{
int flags = UNI_FLAG_NAMED_FUNCTION;
return uaenative_call_function (context, flags);
}
static uae_u32 REGPARAM2 lib_call_function_by_name_async (TrapContext *context)
{
int flags = UNI_FLAG_ASYNCHRONOUS | UNI_FLAG_NAMED_FUNCTION;
return uaenative_call_function (context, flags);
}
static uae_library_trap_def uaenative_functions[] = {
{ lib_init },
{ lib_open },
{ lib_close },
{ lib_expunge },
{ lib_null },
{ lib_open_library },
{ lib_close_library },
{ lib_get_function },
{ lib_call_function },
{ lib_call_function_async, TRAPFLAG_EXTRA_STACK },
{ lib_call_function_by_name },
{ lib_call_function_by_name_async, TRAPFLAG_EXTRA_STACK },
{ NULL },
};
static struct uae_library uaenative_library = {
_T("uaenative.library"),
_T("UAE Native Interface 1.0"),
1, // version
0, // revision
uaenative_functions,
};
void uaenative_install (void)
{
uae_library_install (&uaenative_library);
}
uaecptr uaenative_startup (uaecptr res_addr)
{
return uae_library_startup (res_addr, &uaenative_library);
}
#endif // WITH_UAENATIVE

View File

@ -1023,7 +1023,7 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
if (!memcmp (buf, "PKD\x13", 4) || !memcmp (buf, "PKD\x11", 4)) {
TCHAR *fn;
int sectors = buf[18];
int heads = buf[15];
int reserved = buf[15];
int blocks = (buf[6] << 8) | buf[7];
int blocksize = (buf[10] << 8) | buf[11];
struct zfile *zo;
@ -1034,7 +1034,7 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
uae_u8 *nullsector;
nullsector = xcalloc (uae_u8, blocksize);
sectors /= heads;
sectors /= 2;
if (buf[3] == 0x13) {
off = 52;
if (buf[off - 1] == 1) {
@ -1047,7 +1047,8 @@ static struct zfile *dsq (struct zfile *z, int lzx, int *retcode)
off = 32;
}
if (size < 1760 * 512)
// some Amiga disk images are smaller than full adf for some reason
if (sectors == 11 && size < 1760 * 512)
size = 1760 * 512;
if (zfile_getfilename (zi) && _tcslen (zfile_getfilename (zi))) {