mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
2710b5
This commit is contained in:
parent
9028b9456b
commit
5824a72326
16
cia.cpp
16
cia.cpp
@ -76,7 +76,7 @@ static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
|
||||
|
||||
static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
|
||||
static int ciaatlatch, ciabtlatch;
|
||||
static bool oldled, oldovl, oldcd32mute;
|
||||
static bool oldovl, oldcd32mute;
|
||||
static bool led;
|
||||
static int led_old_brightness;
|
||||
static unsigned long led_cycles_on, led_cycles_off, led_cycle;
|
||||
@ -853,7 +853,7 @@ void CIAA_tod_inc (int cycles)
|
||||
event2_newevent_xx (-1, cycles + TOD_INC_DELAY, 0, CIAA_tod_handler);
|
||||
}
|
||||
|
||||
static void bfe001_change (void)
|
||||
static void check_led (void)
|
||||
{
|
||||
uae_u8 v = ciaapra;
|
||||
bool led2;
|
||||
@ -865,6 +865,12 @@ static void bfe001_change (void)
|
||||
led = led2;
|
||||
led_old_brightness = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void bfe001_change (void)
|
||||
{
|
||||
uae_u8 v = ciaapra;
|
||||
check_led ();
|
||||
if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
|
||||
oldovl = v & 1;
|
||||
if (!oldovl) {
|
||||
@ -1119,6 +1125,10 @@ static uae_u8 ReadCIAB (unsigned int addr)
|
||||
case 12:
|
||||
return ciabsdr;
|
||||
case 13:
|
||||
#if CIAB_DEBUG_IRQ
|
||||
if (ciabicr & (0x80 | 0x40))
|
||||
write_log (_T("CIAB IRQ cleared\n"));
|
||||
#endif
|
||||
tmp = ciabicr & ~0x40;
|
||||
ciabicr = 0;
|
||||
return tmp;
|
||||
@ -1482,7 +1492,6 @@ void CIA_reset (void)
|
||||
kblostsynccnt = 0;
|
||||
serbits = 0;
|
||||
oldcd32mute = 1;
|
||||
oldled = true;
|
||||
resetwarning_phase = resetwarning_timer = 0;
|
||||
heartbeat_cnt = 0;
|
||||
ciab_tod_event_state = 0;
|
||||
@ -1506,6 +1515,7 @@ void CIA_reset (void)
|
||||
DISK_select_set (ciabprb);
|
||||
}
|
||||
map_overlay (0);
|
||||
check_led ();
|
||||
#ifdef SERIAL_PORT
|
||||
if (currprefs.use_serial && !savestate_state)
|
||||
serial_dtr_off (); /* Drop DTR at reset */
|
||||
|
||||
460
custom.cpp
460
custom.cpp
@ -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;
|
||||
|
||||
24
disk.cpp
24
disk.cpp
@ -932,13 +932,22 @@ static bool diskfile_iswriteprotect (struct uae_prefs *p, const TCHAR *fname, in
|
||||
return wrprot1;
|
||||
}
|
||||
|
||||
static bool isrecognizedext (const TCHAR *name)
|
||||
{
|
||||
const TCHAR *ext = _tcsrchr (name, '.');
|
||||
if (ext) {
|
||||
if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img")))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake, bool forcedwriteprotect)
|
||||
{
|
||||
uae_u8 buffer[2 + 2 + 4 + 4];
|
||||
trackid *tid;
|
||||
int num_tracks, size;
|
||||
int canauto;
|
||||
const TCHAR *ext;
|
||||
|
||||
drive_image_free (drv);
|
||||
DISK_validate_filename (p, fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
|
||||
@ -954,13 +963,6 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
|
||||
|
||||
gui_disk_image_change (dnum, fname, drv->wrprot);
|
||||
|
||||
canauto = 0;
|
||||
ext = _tcsrchr (fname, '.');
|
||||
if (ext) {
|
||||
if (!_tcsicmp (ext + 1, _T("adf")) || !_tcsicmp (ext + 1, _T("adz")) || !_tcsicmp (ext + 1, _T("st")) || !_tcsicmp (ext + 1, _T("ima")) || !_tcsicmp (ext + 1, _T("img")))
|
||||
canauto = 1;
|
||||
}
|
||||
|
||||
if (!drv->motoroff) {
|
||||
drv->dskready_up_time = DSKREADY_UP_TIME;
|
||||
drv->dskready_down_time = 0;
|
||||
@ -993,6 +995,12 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
|
||||
zfile_fseek (drv->diskfile, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
canauto = 0;
|
||||
if (isrecognizedext (fname))
|
||||
canauto = 1;
|
||||
if (!canauto && drv->diskfile && isrecognizedext (zfile_getname (drv->diskfile)))
|
||||
canauto = 1;
|
||||
|
||||
if (drv->catweasel) {
|
||||
|
||||
drv->wrprot = true;
|
||||
|
||||
74
drawing.cpp
74
drawing.cpp
@ -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
|
||||
|
||||
13
events.cpp
13
events.cpp
@ -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 ();
|
||||
|
||||
@ -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)
|
||||
|
||||
19
filesys.asm
19
filesys.asm
@ -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
|
||||
|
||||
|
||||
17
filesys.cpp
17
filesys.cpp
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
34
gencpu.cpp
34
gencpu.cpp
@ -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");
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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[] =
|
||||
{
|
||||
{
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
49
include/uaenative.h
Normal 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
80
include/uni_common.h
Normal 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_
|
||||
4
main.cpp
4
main.cpp
@ -56,6 +56,7 @@
|
||||
#include "gayle.h"
|
||||
#include "gfxboard.h"
|
||||
#include "luascript.h"
|
||||
#include "uaenative.h"
|
||||
#ifdef RETROPLATFORM
|
||||
#include "rp.h"
|
||||
#endif
|
||||
@ -1004,6 +1005,9 @@ void virtualdevice_init (void)
|
||||
#if defined (BSDSOCKET)
|
||||
bsdlib_install ();
|
||||
#endif
|
||||
#ifdef WITH_UAENATIVE
|
||||
uaenative_install ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int real_main2 (int argc, TCHAR **argv)
|
||||
|
||||
40
memory.cpp
40
memory.cpp
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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" />
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
851
uaenative.cpp
Normal 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)®s;
|
||||
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, ®s);
|
||||
#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
|
||||
@ -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))) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user