mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
3300b9
This commit is contained in:
parent
ac2410d9ef
commit
d3d6eb18b2
8
ar.cpp
8
ar.cpp
@ -98,8 +98,10 @@
|
||||
* 0x400002/0x400003: mirrors 0x400000/0x400001
|
||||
* 0x400006/0x400007: when written to, turns chip-ram overlay off
|
||||
*
|
||||
* cartridge hardware also snoops CPU accesses to custom chip
|
||||
* registers (DFF000-DFF1FE). All CPU custom chip accesses are
|
||||
* Reset condition: first chip ram (or non-custom register) write after hardware reset.
|
||||
*
|
||||
* cartridge hardware also snoops CPU write accesses to custom chip
|
||||
* registers (DFF000-DFF1FE). All CPU custom chip write accesses are
|
||||
* saved to RAM at 0x44f000-0x44f1ff. Note that emulated AR3 also
|
||||
* saves copper's custom chip accesses. This fix stops programs
|
||||
* that try to trick AR by using copper to update write-only
|
||||
@ -221,8 +223,6 @@
|
||||
#define write_log_debug
|
||||
#endif
|
||||
|
||||
extern void activate_debugger (void);
|
||||
|
||||
static const TCHAR *cart_memnames[] = { NULL, _T("hrtmon"), _T("arhrtmon"), _T("superiv") };
|
||||
|
||||
// Action Replay 2/3
|
||||
|
||||
109
autoconf.cpp
109
autoconf.cpp
@ -10,6 +10,8 @@
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
#define NEW_TRAP_DEBUG 0
|
||||
|
||||
#include "options.h"
|
||||
#include "uae.h"
|
||||
#include "memory.h"
|
||||
@ -33,6 +35,7 @@ uaecptr EXPANSION_bootcode, EXPANSION_nullfunc;
|
||||
|
||||
uaecptr rtarea_base = RTAREA_DEFAULT;
|
||||
uae_sem_t hardware_trap_event[RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE];
|
||||
uae_sem_t hardware_trap_event2[RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE];
|
||||
|
||||
static uaecptr rt_trampoline_ptr, trap_entry;
|
||||
extern volatile uae_atomic hwtrap_waiting;
|
||||
@ -97,6 +100,12 @@ static bool rtarea_trap_status(uaecptr addr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
static bool rtarea_trap_status_extra(uaecptr addr)
|
||||
{
|
||||
if (addr >= RTAREA_TRAP_STATUS + 0x100 && addr < RTAREA_TRAP_STATUS + 0x100 + (RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM) * RTAREA_TRAP_STATUS_SIZE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static uae_u8 *REGPARAM2 rtarea_xlate (uaecptr addr)
|
||||
{
|
||||
@ -119,20 +128,42 @@ static uae_u32 REGPARAM2 rtarea_lget (uaecptr addr)
|
||||
static uae_u32 REGPARAM2 rtarea_wget (uaecptr addr)
|
||||
{
|
||||
addr &= 0xFFFF;
|
||||
|
||||
uaecptr addr2 = addr - RTAREA_TRAP_STATUS;
|
||||
|
||||
if (rtarea_trap_status(addr)) {
|
||||
int trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr2 / RTAREA_TRAP_STATUS_SIZE;
|
||||
// lock attempt
|
||||
if (trap_offset == 2) {
|
||||
if (rtarea_bank.baseaddr[addr + 1] & 0x80) {
|
||||
return rtarea_bank.baseaddr[addr + 1];
|
||||
}
|
||||
rtarea_bank.baseaddr[addr + 1] |= 0x80;
|
||||
rtarea_bank.baseaddr[addr + 0] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return (rtarea_bank.baseaddr[addr] << 8) + rtarea_bank.baseaddr[addr + 1];
|
||||
}
|
||||
static uae_u32 REGPARAM2 rtarea_bget (uaecptr addr)
|
||||
{
|
||||
addr &= 0xFFFF;
|
||||
|
||||
hwtrap_check_int();
|
||||
if (rtarea_trap_status(addr)) {
|
||||
uaecptr addr2 = addr - RTAREA_TRAP_STATUS;
|
||||
int trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr2 / RTAREA_TRAP_STATUS_SIZE;
|
||||
if (trap_offset == 0) {
|
||||
// 0 = busy wait, 1 = Wait()
|
||||
rtarea_bank.baseaddr[addr] = trap_mode ? 1 : 0;
|
||||
rtarea_bank.baseaddr[addr] = trap_mode == 1 ? 1 : 0;
|
||||
}
|
||||
uae_u8 v = rtarea_bank.baseaddr[addr];
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("GET TRAP SLOT %d OFFSET %d: V=%02x\n"), trap_slot, trap_offset, v);
|
||||
#endif
|
||||
return v;
|
||||
} else if (addr == RTAREA_INTREQ + 0) {
|
||||
rtarea_bank.baseaddr[addr] = atomic_bit_test_and_reset(&uae_int_requested, 0);
|
||||
//write_log(rtarea_bank.baseaddr[addr] ? _T("+") : _T("-"));
|
||||
@ -145,7 +176,6 @@ static uae_u32 REGPARAM2 rtarea_bget (uaecptr addr)
|
||||
rtarea_bank.baseaddr[addr] = 0;
|
||||
}
|
||||
}
|
||||
hwtrap_check_int();
|
||||
return rtarea_bank.baseaddr[addr];
|
||||
}
|
||||
|
||||
@ -155,7 +185,7 @@ static bool rtarea_write(uaecptr addr)
|
||||
return true;
|
||||
if (addr >= RTAREA_SYSBASE && addr < RTAREA_SYSBASE + 4)
|
||||
return true;
|
||||
return rtarea_trap_data(addr) || rtarea_trap_status(addr);
|
||||
return rtarea_trap_data(addr) || rtarea_trap_status(addr) || rtarea_trap_status_extra(addr);
|
||||
}
|
||||
|
||||
static void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value)
|
||||
@ -172,16 +202,25 @@ static void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value)
|
||||
addr -= RTAREA_TRAP_STATUS;
|
||||
int trap_offset = addr & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr / RTAREA_TRAP_STATUS_SIZE;
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("PUT TRAP SLOT %d OFFSET %d: V=%02x\n"), trap_slot, trap_offset, (uae_u8)value);
|
||||
#endif
|
||||
if (trap_offset == RTAREA_TRAP_STATUS_SECOND) {
|
||||
write_log(_T("TRAP SLOT %d PRI=%02x\n"), trap_slot, (uae_u8)value);
|
||||
}
|
||||
if (trap_offset == RTAREA_TRAP_STATUS_SECOND + 3) {
|
||||
uae_u8 v = (uae_u8)value;
|
||||
if (v != 0xff && v != 0xfe && v != 0x01 && v != 02)
|
||||
write_log(_T("trap %d status = %02x\n"), trap_slot, v);
|
||||
if (v == 0xfe)
|
||||
if (v != 0xff && v != 0xfd && v != 0x01 && v != 0x02 && v != 0x03 && v != 0x04)
|
||||
write_log(_T("TRAP SLOT %d STATUS = %02x\n"), trap_slot, v);
|
||||
if (v == 0xfd)
|
||||
atomic_dec(&hwtrap_waiting);
|
||||
if (v == 0x01)
|
||||
atomic_dec(&hwtrap_waiting);
|
||||
if (v == 0x01 || v == 0x02) {
|
||||
// signal call_hardware_trap_back()
|
||||
// 1 = interrupt ack
|
||||
// 2 = interrupt -> task ack
|
||||
// 3 = hwtrap_entry ack
|
||||
if (v == 0x01 || v == 0x02 || v == 0x03) {
|
||||
// signal call_hardware_trap_back_back()
|
||||
uae_sem_post(&hardware_trap_event[trap_slot]);
|
||||
}
|
||||
}
|
||||
@ -191,18 +230,42 @@ static void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value)
|
||||
{
|
||||
addr &= 0xffff;
|
||||
value &= 0xffff;
|
||||
|
||||
if (!rtarea_write(addr))
|
||||
return;
|
||||
rtarea_bput (addr, value >> 8);
|
||||
rtarea_bput (addr + 1, value & 0xff);
|
||||
if (!rtarea_trap_status(addr))
|
||||
return;
|
||||
addr -= RTAREA_TRAP_STATUS;
|
||||
int trap_offset = addr & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr / RTAREA_TRAP_STATUS_SIZE;
|
||||
if (trap_offset == 0) {
|
||||
//write_log(_T("TRAP %d (%d)\n"), trap_slot, value);
|
||||
call_hardware_trap(rtarea_bank.baseaddr, rtarea_base, trap_slot);
|
||||
|
||||
uaecptr addr2 = addr - RTAREA_TRAP_STATUS;
|
||||
|
||||
if (rtarea_trap_status(addr)) {
|
||||
int trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr2 / RTAREA_TRAP_STATUS_SIZE;
|
||||
if (trap_offset == 2) {
|
||||
value = 0;
|
||||
if ((rtarea_bank.baseaddr[addr + 1] & 0x80) == 0) {
|
||||
write_log(_T("TRAP SLOT %d unlock without allocation!\n"), trap_slot);
|
||||
}
|
||||
rtarea_bank.baseaddr[addr + 0] = value >> 8;
|
||||
rtarea_bank.baseaddr[addr + 1] = (uae_u8)value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rtarea_bank.baseaddr[addr + 0] = value >> 8;
|
||||
rtarea_bank.baseaddr[addr + 1] = (uae_u8)value;
|
||||
|
||||
if (rtarea_trap_status(addr)) {
|
||||
int trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr2 / RTAREA_TRAP_STATUS_SIZE;
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("PUT TRAP SLOT %d OFFSET %d: V=%04x\n"), trap_slot, trap_offset, (uae_u16)value);
|
||||
#endif
|
||||
if (trap_offset == 0) {
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("TRAP SLOT %d NUM=%d\n"), trap_slot, value);
|
||||
#endif
|
||||
call_hardware_trap(rtarea_bank.baseaddr, rtarea_base, trap_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value)
|
||||
@ -214,6 +277,15 @@ static void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value)
|
||||
rtarea_bank.baseaddr[addr + 1] = value >> 16;
|
||||
rtarea_bank.baseaddr[addr + 2] = value >> 8;
|
||||
rtarea_bank.baseaddr[addr + 3] = value >> 0;
|
||||
|
||||
if (rtarea_trap_status(addr)) {
|
||||
addr -= RTAREA_TRAP_STATUS;
|
||||
int trap_offset = addr & (RTAREA_TRAP_STATUS_SIZE - 1);
|
||||
int trap_slot = addr / RTAREA_TRAP_STATUS_SIZE;
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("PUT TRAP SLOT %d OFFSET %d: V=%08x\n"), trap_slot, trap_offset, value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void rtarea_reset(void)
|
||||
@ -414,6 +486,7 @@ void rtarea_init(void)
|
||||
|
||||
for (int i = 0; i < RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE; i++) {
|
||||
uae_sem_init(&hardware_trap_event[i], 0, 0);
|
||||
uae_sem_init(&hardware_trap_event2[i], 0, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
30
cfgfile.cpp
30
cfgfile.cpp
@ -1770,6 +1770,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
|
||||
_tcscat (s, _T(",nvsync"));
|
||||
if (cr->rtg)
|
||||
_tcscat (s, _T(",rtg"));
|
||||
if (cr->exit)
|
||||
_tcscat(s, _T(",exit"));
|
||||
if (cr->filterprofile[0]) {
|
||||
TCHAR *se = cfgfile_escape(cr->filterprofile, _T(","), true);
|
||||
s += _stprintf(s, _T(",filter=%s"), cr->filterprofile);
|
||||
@ -3252,8 +3254,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
|
||||
tmpbuf[sizeof tmpbuf / sizeof (TCHAR) - 1] = '\0';
|
||||
|
||||
int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1, hres = 0;
|
||||
bool locked = false;
|
||||
bool rtg = false;
|
||||
bool locked = false, rtg = false, exit = false;
|
||||
bool cmdmode = false;
|
||||
double rate = -1;
|
||||
int rpct = 0;
|
||||
@ -3327,6 +3328,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
|
||||
framelength = 0;
|
||||
if (!_tcsnicmp(tmpp, _T("rtg"), 3))
|
||||
rtg = true;
|
||||
if (!_tcsnicmp(tmpp, _T("exit"), 4))
|
||||
exit = true;
|
||||
}
|
||||
tmpp = next;
|
||||
if (tmpp >= end)
|
||||
@ -3355,6 +3358,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
|
||||
cr->vsync = vsync;
|
||||
cr->locked = locked;
|
||||
cr->rtg = rtg;
|
||||
cr->exit = exit;
|
||||
cr->framelength = framelength;
|
||||
cr->rate = rate;
|
||||
_tcscpy(cr->commands, cmd);
|
||||
@ -3801,6 +3805,28 @@ static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struc
|
||||
_tcscpy (uci->filesys, val);
|
||||
if (!_tcsicmp (key, _T("device")))
|
||||
_tcscpy (uci->devname, val);
|
||||
if (!_tcsicmp(key, _T("badblocks"))) {
|
||||
TCHAR *p = val;
|
||||
while (p && *p && uci->badblock_num < MAX_UAEDEV_BADBLOCKS) {
|
||||
struct uaedev_badblock *bb = &uci->badblocks[uci->badblock_num];
|
||||
if (!_istdigit(*p))
|
||||
break;
|
||||
bb->first = _tstol(p);
|
||||
bb->last = bb->first;
|
||||
TCHAR *p1 = _tcschr(p, ',');
|
||||
TCHAR *p2 = NULL;
|
||||
if (p1) {
|
||||
p2 = p1 + 1;
|
||||
*p1 = 0;
|
||||
}
|
||||
p1 = _tcschr(p, '-');
|
||||
if (p1) {
|
||||
bb->last = _tstol(p1 + 1);
|
||||
}
|
||||
uci->badblock_num++;
|
||||
p = p2;
|
||||
}
|
||||
}
|
||||
xfree (val);
|
||||
xfree (key);
|
||||
}
|
||||
|
||||
@ -4283,9 +4283,15 @@ static void init_hz (bool checkvposw)
|
||||
|
||||
if (hsyncendpos < 2)
|
||||
hsyncendpos = 2;
|
||||
|
||||
if (hsyncstartpos - hsyncendpos < maxhpos / 2)
|
||||
hsyncstartpos = maxhpos;
|
||||
|
||||
} else {
|
||||
|
||||
hsyncstartpos = maxhpos_short + 13;
|
||||
hsyncendpos = 24;
|
||||
|
||||
}
|
||||
hpos_offset = 0;
|
||||
eventtab[ev_hsync].oldcycles = get_cycles ();
|
||||
@ -5639,7 +5645,7 @@ static void BLTBPTH (int hpos, uae_u16 v)
|
||||
{
|
||||
maybe_blit (hpos, 0);
|
||||
if (bltstate != BLT_done && currprefs.blitter_cycle_exact && currprefs.cpu_cycle_exact) {
|
||||
bltptx = (bltapt & 0xffff) | ((uae_u32)v << 16);
|
||||
bltptx = (bltbpt & 0xffff) | ((uae_u32)v << 16);
|
||||
bltptxpos = hpos;
|
||||
bltptxc = 2;
|
||||
} else {
|
||||
|
||||
@ -396,12 +396,13 @@ static void call_card_init(int index)
|
||||
addrbank *ab, *abe;
|
||||
uae_u8 code;
|
||||
uae_u32 expamem_z3_pointer_old;
|
||||
card_data *cd = &cards[ecard];
|
||||
|
||||
expamem_bank.name = cards[ecard].name ? cards[ecard].name : _T("None");
|
||||
if (cards[ecard].initnum)
|
||||
ab = cards[ecard].initnum(0);
|
||||
expamem_bank.name = cd->name ? cd->name : _T("None");
|
||||
if (cd->initnum)
|
||||
ab = cd->initnum(0);
|
||||
else
|
||||
ab = cards[ecard].initrc(cards[ecard].rc);
|
||||
ab = cd->initrc(cd->rc);
|
||||
expamem_z3_size = 0;
|
||||
if (ab == &expamem_none) {
|
||||
expamem_init_clear();
|
||||
@ -460,8 +461,8 @@ static void call_card_init(int index)
|
||||
expamem_z3_sum += expamem_z3_size;
|
||||
|
||||
expamem_z3_pointer_old = expamem_z3_pointer;
|
||||
// align 32M boards (FastLane is 32M and needs to be aligned)
|
||||
if (expamem_z3_size <= 32 * 1024 * 1024)
|
||||
// align non-UAE 32M boards (FastLane is 32M and needs to be aligned)
|
||||
if (expamem_z3_size <= 32 * 1024 * 1024 && !(cd->flags & 16))
|
||||
expamem_z3_pointer = (expamem_z3_pointer + expamem_z3_size - 1) & ~(expamem_z3_size - 1);
|
||||
|
||||
expamem_z3_sum += expamem_z3_pointer - expamem_z3_pointer_old;
|
||||
@ -483,7 +484,7 @@ static void call_card_init(int index)
|
||||
if (ab) {
|
||||
// non-NULL: not using expamem_bank
|
||||
expamem_bank_current = ab;
|
||||
if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
|
||||
if ((cd->flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
|
||||
map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
|
||||
map_banks(&dummy_bank, 0xE8, 1, 0);
|
||||
} else {
|
||||
@ -492,7 +493,7 @@ static void call_card_init(int index)
|
||||
map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
|
||||
}
|
||||
} else {
|
||||
if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
|
||||
if ((cd->flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
|
||||
map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
|
||||
map_banks(&dummy_bank, 0xE8, 1, 0);
|
||||
expamem_bank_current = &expamem_bank;
|
||||
@ -2312,14 +2313,14 @@ void expamem_reset (void)
|
||||
if (z3fastmem_bank.baseaddr != NULL) {
|
||||
bool alwaysmapz3 = currprefs.z3_mapping_mode != Z3MAPPING_REAL;
|
||||
z3num = 0;
|
||||
cards[cardno].flags = 2 | 1;
|
||||
cards[cardno].flags = 16 | 2 | 1;
|
||||
cards[cardno].name = _T("Z3Fast");
|
||||
cards[cardno].initnum = expamem_init_z3fastmem;
|
||||
cards[cardno++].map = expamem_map_z3fastmem;
|
||||
if (alwaysmapz3 || expamem_z3hack(&currprefs))
|
||||
map_banks_z3(&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16);
|
||||
if (z3fastmem2_bank.baseaddr != NULL) {
|
||||
cards[cardno].flags = 2 | 1;
|
||||
cards[cardno].flags = 16 | 2 | 1;
|
||||
cards[cardno].name = _T("Z3Fast2");
|
||||
cards[cardno].initnum = expamem_init_z3fastmem2;
|
||||
cards[cardno++].map = expamem_map_z3fastmem2;
|
||||
@ -2331,7 +2332,7 @@ void expamem_reset (void)
|
||||
map_banks_z3(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16);
|
||||
#ifdef PICASSO96
|
||||
if (currprefs.rtgboards[0].rtgmem_size && currprefs.rtgboards[0].rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) {
|
||||
cards[cardno].flags = 4 | 1;
|
||||
cards[cardno].flags = 16 | 4 | 1;
|
||||
cards[cardno].name = _T("Z3RTG");
|
||||
cards[cardno].initnum = expamem_init_gfxcard_z3;
|
||||
cards[cardno++].map = expamem_map_gfxcard_z3;
|
||||
|
||||
235
filesys.asm
235
filesys.asm
@ -45,6 +45,7 @@ TRAP_STATUS = $F000
|
||||
TRAP_STATUS_SLOT_SIZE = 8
|
||||
TRAP_STATUS_SECOND = 4
|
||||
|
||||
TRAP_STATUS_LOCK_WORD = 2
|
||||
TRAP_STATUS_STATUS2 = 2
|
||||
TRAP_STATUS_STATUS = 3
|
||||
|
||||
@ -458,15 +459,15 @@ trap_task_check:
|
||||
.nexttrap
|
||||
tst.b TRAP_STATUS_STATUS(a1)
|
||||
beq.s .next
|
||||
cmp.b #$fe,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a1)
|
||||
cmp.b #$fd,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a1)
|
||||
bne.s .next
|
||||
addq.l #1,d7
|
||||
lea TRAP_DATA_SECOND(a0),a4
|
||||
lea TRAP_DATA_SECOND+4(a0),a4
|
||||
lea TRAP_STATUS_SECOND(a1),a5
|
||||
movem.l d6/d7/a0/a1/a4/a5/a6,-(sp)
|
||||
move.w (a5),d4 ;command
|
||||
movem.l 4(a4),a0-a2
|
||||
movem.l 4(a4),d0-d2
|
||||
movem.l (a4),a0-a2
|
||||
movem.l (a4),d0-d2
|
||||
cmp.w #18,d4
|
||||
bne.s .notcalllib
|
||||
bsr.w hw_call_lib
|
||||
@ -477,7 +478,7 @@ trap_task_check:
|
||||
bsr.w hw_call_func
|
||||
.calldone
|
||||
movem.l (sp)+,d6/d7/a0-a1/a4/a5/a6
|
||||
move.l d0,4(a4)
|
||||
move.l d0,(a4)
|
||||
move.b #2,TRAP_STATUS_STATUS(a5)
|
||||
.next
|
||||
add.w #TRAP_DATA_SLOT_SIZE,a0
|
||||
@ -1931,7 +1932,8 @@ createport:
|
||||
lea 20(a2),a0
|
||||
bsr.w newlist
|
||||
move.l a2,a0
|
||||
.f move.l a0,d0
|
||||
.f
|
||||
move.l a0,d0
|
||||
movem.l (sp)+,d2/a2/a6
|
||||
rts
|
||||
|
||||
@ -1952,7 +1954,8 @@ createio:
|
||||
move.b #10,8(a0) ;NT_MESSAGE
|
||||
move.w d2,18(a0)
|
||||
move.l a2,14(a0)
|
||||
.f tst.l d0
|
||||
.f
|
||||
tst.l d0
|
||||
movem.l (sp)+,d2/a2/a6
|
||||
rts
|
||||
|
||||
@ -1977,7 +1980,8 @@ allocdevice
|
||||
tst.l d1
|
||||
bne.s .f
|
||||
move.l a2,d0
|
||||
.f tst.l d0
|
||||
.f
|
||||
tst.l d0
|
||||
movem.l (sp)+,d2-d3/a2/a6
|
||||
rts
|
||||
|
||||
@ -2007,7 +2011,8 @@ createtask:
|
||||
move.l a1,d2
|
||||
jsr -$011a(a6) ;AddTask
|
||||
move.l d2,d0
|
||||
.f movem.l (sp)+,d2/d3/d4/a2/a3/a6
|
||||
.f
|
||||
movem.l (sp)+,d2/d3/d4/a2/a3/a6
|
||||
rts
|
||||
|
||||
; mousehack/tablet
|
||||
@ -2019,24 +2024,34 @@ mousehack_init:
|
||||
bsr createtask
|
||||
rts
|
||||
|
||||
mhdoiotimer:
|
||||
mhdoio:
|
||||
sub.w #24,sp
|
||||
clr.l (a2)
|
||||
clr.l 14(a2)
|
||||
clr.l 18(a2)
|
||||
move.l a2,a0
|
||||
move.l sp,a1
|
||||
moveq #24/4-1,d0
|
||||
.mhdoioc
|
||||
move.l (a0)+,(a1)+
|
||||
dbf d0,.mhdoioc
|
||||
cmp.w #36,20(a6)
|
||||
bcc.s .mhdoio36
|
||||
move.l MH_TM(a5),a1
|
||||
move.w #10,28(a1) ;TR_GETSYSTIME
|
||||
move.b #1,30(a1) ;IOF_QUICK
|
||||
jsr -$01c8(a6) ;DoIO
|
||||
move.l MH_TM(a5),a1
|
||||
move.l 32(a1),14(a2)
|
||||
move.l 36(a1),18(a2)
|
||||
move.l MH_IO(a5),a1
|
||||
move.b #1,30(a1) ;IOF_QUICK
|
||||
jsr -$01c8(a6) ;DoIO
|
||||
rts
|
||||
mhdoio:
|
||||
clr.l 14(a2)
|
||||
clr.l 18(a2)
|
||||
move.l 32(a1),14(sp)
|
||||
move.l 36(a1),18(sp)
|
||||
.mhdoio36
|
||||
move.l MH_IO(a5),a1
|
||||
move.w #11,28(a1) ;IND_WRITEEVENT
|
||||
move.l #22,36(a1) ;sizeof(struct InputEvent)
|
||||
move.b #1,30(a1) ;IOF_QUICK
|
||||
move.l sp,40(a1)
|
||||
jsr -$01c8(a6) ;DoIO
|
||||
add.w #24,sp
|
||||
rts
|
||||
|
||||
MH_E = 0
|
||||
@ -2358,11 +2373,7 @@ mhloop
|
||||
move.l d0,MH_FOO_LIMITCNT(a3)
|
||||
.nodims
|
||||
|
||||
move.l MH_IO(a5),a1
|
||||
lea MH_IEV(a5),a2
|
||||
move.w #11,28(a1) ;IND_WRITEEVENT
|
||||
move.l #22,36(a1) ;sizeof(struct InputEvent)
|
||||
move.l a2,40(a1)
|
||||
|
||||
move.b MH_E(a4),d0
|
||||
cmp.w #39,d7
|
||||
@ -2458,7 +2469,38 @@ mhloop
|
||||
clr.l (a1) ;TAG_DONE
|
||||
|
||||
bsr.w mhdoio
|
||||
|
||||
|
||||
.notablet
|
||||
move.b MH_E(a4),d0
|
||||
btst #MH_TABLET,d0
|
||||
bne.s .yestablet
|
||||
btst #MH_MOUSEHACK,d0
|
||||
beq.w mhloop
|
||||
.yestablet
|
||||
|
||||
move.l MH_FOO_INTBASE(a3),a0
|
||||
|
||||
move.w MH_ABSX(a4),d0
|
||||
move.w 34+14(a0),d1
|
||||
add.w d1,d1
|
||||
sub.w d1,d0
|
||||
bpl.s .xn
|
||||
moveq #0,d0
|
||||
.xn
|
||||
move.w d0,10(a2) ;ie_Addr/X
|
||||
|
||||
move.w MH_ABSY(a4),d0
|
||||
move.w 34+12(a0),d1
|
||||
add.w d1,d1
|
||||
sub.w d1,d0
|
||||
bpl.s .yn
|
||||
moveq #0,d0
|
||||
.yn
|
||||
move.w d0,12(a2) ;ie_Addr/Y
|
||||
|
||||
btst #MH_TABLET,MH_E(a4)
|
||||
beq.s .notablet2
|
||||
|
||||
;create mouse button events if button state changed
|
||||
move.w #$68,d3 ;IECODE_LBUTTON->IECODE_RBUTTON->IECODE_MBUTTON
|
||||
moveq #1,d2
|
||||
@ -2471,16 +2513,14 @@ mhloop
|
||||
cmp.l d0,d1
|
||||
beq.s .nobut
|
||||
|
||||
clr.l (a2)
|
||||
move.w #$0200,4(a2) ;ie_Class=IECLASS_RAWMOUSE,ie_SubClass=0
|
||||
clr.l 10(a2) ;ie_Addr/X+Y
|
||||
move.w d3,d1
|
||||
tst.b d0
|
||||
bne.s .butdown
|
||||
bset #7,d1 ;IECODE_UP_PREFIX
|
||||
.butdown
|
||||
move.w d1,6(a2) ;ie_Code
|
||||
clr.w 8(a2) ;ie_Qualifier
|
||||
bsr.w buttonstoqual
|
||||
|
||||
bsr.w mhdoio
|
||||
|
||||
@ -2491,38 +2531,26 @@ mhloop
|
||||
bne.s .nextbut
|
||||
move.l d4,MH_FOO_BUTTONS(a3)
|
||||
|
||||
.notablet
|
||||
|
||||
move.b MH_E(a4),d0
|
||||
btst #MH_MOUSEHACK,d0
|
||||
.notablet2
|
||||
btst #MH_MOUSEHACK,MH_E(a4)
|
||||
beq.w mhloop
|
||||
|
||||
clr.l (a2)
|
||||
move.w #$0400,4(a2) ;IECLASS_POINTERPOS
|
||||
clr.w 6(a2) ;ie_Code
|
||||
|
||||
bsr.w buttonstoqual
|
||||
cmp.w #36,20(a6)
|
||||
bcs.s .mhvpre36
|
||||
move.l a6,-(sp)
|
||||
move.l MH_IO(a5),a6
|
||||
move.l 20(a6),a6
|
||||
jsr -$2a(a6) ;PeekQualifier
|
||||
move.l (sp)+,a6
|
||||
and.w #$7fff,d0
|
||||
move.w d0,8(a2) ;ie_Qualifier
|
||||
.mhvpre36
|
||||
|
||||
move.l MH_FOO_INTBASE(a3),a0
|
||||
|
||||
move.w MH_ABSX(a4),d0
|
||||
move.w 34+14(a0),d1
|
||||
add.w d1,d1
|
||||
sub.w d1,d0
|
||||
bpl.s .xn
|
||||
moveq #0,d0
|
||||
.xn
|
||||
move.w d0,10(a2)
|
||||
|
||||
move.w MH_ABSY(a4),d0
|
||||
move.w 34+12(a0),d1
|
||||
add.w d1,d1
|
||||
sub.w d1,d0
|
||||
bpl.s .yn
|
||||
moveq #0,d0
|
||||
.yn
|
||||
move.w d0,12(a2)
|
||||
|
||||
bsr.w mhdoiotimer
|
||||
bsr.w mhdoio
|
||||
|
||||
bra.w mhloop
|
||||
|
||||
@ -3221,7 +3249,7 @@ hwtrap_install:
|
||||
rts
|
||||
|
||||
hwtrap_entry:
|
||||
movem.l d0-d1/a0-a3,-(sp)
|
||||
movem.l d0-d1/a0-a1,-(sp)
|
||||
.retry
|
||||
move.l #TRAP_STATUS,d0
|
||||
bsr.w getrtbase
|
||||
@ -3230,7 +3258,7 @@ hwtrap_entry:
|
||||
bsr.w getrtbase
|
||||
moveq #TRAP_DATA_NUM-1,d0
|
||||
.nexttrap
|
||||
tas.b TRAP_STATUS_STATUS(a1)
|
||||
tst.w TRAP_STATUS_LOCK_WORD(a1)
|
||||
beq.s .foundfree
|
||||
.nexttrap2
|
||||
add.w #TRAP_DATA_SLOT_SIZE,a0
|
||||
@ -3238,12 +3266,7 @@ hwtrap_entry:
|
||||
dbf d0,.nexttrap
|
||||
bra.s .retry
|
||||
.foundfree
|
||||
tst TRAP_STATUS_STATUS(a1)
|
||||
bpl.s .nexttrap2
|
||||
|
||||
; clear secondary status
|
||||
clr.b TRAP_STATUS_STATUS2(a1)
|
||||
|
||||
; store registers
|
||||
movem.l d2-d7,TRAP_DATA_DATA+2*4(a0)
|
||||
movem.l a2-a6,TRAP_DATA_DATA+8*4+2*4(a0)
|
||||
@ -3255,27 +3278,62 @@ hwtrap_entry:
|
||||
move.l a0,a2 ; data
|
||||
move.l a1,a3 ; status
|
||||
|
||||
move.l 4.w,a6
|
||||
clr.l TRAP_DATA_TASKWAIT(a2)
|
||||
tst.b (a3)
|
||||
beq.s .nowait
|
||||
move.l 4.w,a6
|
||||
sub.l a1,a1
|
||||
jsr -$126(a6) ; FindTask
|
||||
move.l d0,TRAP_DATA_TASKWAIT(a2)
|
||||
.nowait
|
||||
|
||||
; trap number, this triggers the trap
|
||||
move.w 6*4(sp),(a3)
|
||||
move.w 4*4(sp),(a3)
|
||||
|
||||
move.l #$80000000,d5
|
||||
move.w #10000,d4
|
||||
|
||||
.waittrap
|
||||
tst.b TRAP_STATUS_STATUS2(a3)
|
||||
bne.s .triggered
|
||||
cmp.b #$fe,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a3)
|
||||
bne.s .waittrap1
|
||||
move.b #4,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a3)
|
||||
move.l a2,a0
|
||||
move.l a3,a1
|
||||
moveq #1,d0
|
||||
bsr.w hwtrap_command
|
||||
move.b #3,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a3)
|
||||
bra.s .waittrap
|
||||
.waittrap1
|
||||
tst.l TRAP_DATA_TASKWAIT(a2)
|
||||
beq.s .waittrap
|
||||
bne.s .waittrap2
|
||||
cmp.l #$80000000,d5
|
||||
bne.s .waittrap
|
||||
subq.w #1,d4
|
||||
bpl.s .waittrap
|
||||
; lower priority after some busy wait rounds
|
||||
sub.l a1,a1
|
||||
jsr -$126(a6) ; FindTask
|
||||
move.l d0,a1
|
||||
moveq #-120,d0
|
||||
jsr -$12c(a6) ; SetTaskPri
|
||||
move.l d0,d5
|
||||
bra.s .waittrap
|
||||
.waittrap2
|
||||
move.l #$100,d0
|
||||
jsr -$13e(a6) ; Wait
|
||||
bra.s .waittrap
|
||||
.triggered
|
||||
cmp.l #$80000000,d5
|
||||
beq.s .triggered1
|
||||
; restore original priority
|
||||
sub.l a1,a1
|
||||
jsr -$126(a6) ; FindTask
|
||||
move.l d0,a1
|
||||
move.l d5,d0
|
||||
jsr -$12c(a6) ; SetTaskPri
|
||||
.triggered1
|
||||
move.b #1,TRAP_STATUS_STATUS2(a3)
|
||||
|
||||
move.l a2,a0
|
||||
@ -3285,17 +3343,17 @@ hwtrap_entry:
|
||||
movem.l TRAP_DATA_DATA(a0),d0-d7
|
||||
movem.l TRAP_DATA_DATA+8*4+2*4(a0),a2-a6
|
||||
move.l TRAP_DATA_DATA+8*4(a0),-(sp) ;A0
|
||||
move.l TRAP_DATA_DATA+9*4(a0),-(sp) ;A1
|
||||
move.l TRAP_DATA_DATA+8*4+1*4(a0),-(sp) ;A1
|
||||
|
||||
clr.l TRAP_DATA_TASKWAIT(a0)
|
||||
|
||||
; free trap data entry
|
||||
clr.b TRAP_STATUS_STATUS(a1)
|
||||
clr.w TRAP_STATUS_LOCK_WORD(a1)
|
||||
|
||||
move.l (sp)+,a1
|
||||
move.l (sp)+,a0
|
||||
; pop trap number and d0-d1/a0-a3
|
||||
lea 6*4+2(sp),sp
|
||||
; pop trap number and d0-d1/a0-a1
|
||||
lea 4*4+2(sp),sp
|
||||
rts
|
||||
|
||||
hwtrap_interrupt:
|
||||
@ -3319,7 +3377,15 @@ hwtrap_interrupt:
|
||||
tst.b TRAP_STATUS_STATUS(a1)
|
||||
beq.s .next
|
||||
cmp.b #$ff,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a1)
|
||||
beq.s .foundactive
|
||||
bne.s .next
|
||||
moveq #0,d0
|
||||
bsr.s hwtrap_command
|
||||
beq.s .trapdone
|
||||
move.b #$fd,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a1)
|
||||
bra.s .checkagain
|
||||
.trapdone
|
||||
move.b #1,TRAP_STATUS_SECOND+TRAP_STATUS_STATUS(a1)
|
||||
bra.s .checkagain
|
||||
.next
|
||||
add.w #TRAP_DATA_SLOT_SIZE,a0
|
||||
add.w #TRAP_STATUS_SLOT_SIZE,a1
|
||||
@ -3358,35 +3424,48 @@ hwtrap_interrupt:
|
||||
movem.l (sp)+,d2/d3/a2/a3
|
||||
rts
|
||||
|
||||
.foundactive
|
||||
movem.l d1-d4/a1-a6,-(sp)
|
||||
lea TRAP_DATA_SECOND(a0),a4
|
||||
; a0: data
|
||||
; a1: status
|
||||
; d0: task=1,int=0
|
||||
hwtrap_command:
|
||||
movem.l d1-d5/a1-a5,-(sp)
|
||||
move.w d0,d5
|
||||
lea TRAP_DATA_SECOND+4(a0),a4
|
||||
lea TRAP_STATUS_SECOND(a1),a5
|
||||
move.w (a5),d4 ;command
|
||||
add.w d4,d4
|
||||
lea trapjumps(pc),a3
|
||||
move.w 0(a3,d4.w),d1
|
||||
bne.s .intisok
|
||||
tst.w d5
|
||||
beq.s .needint
|
||||
move.w #hw_call_lib-trapjumps,d1
|
||||
cmp.w #2*18,d4
|
||||
beq.s .intisok
|
||||
move.w #hw_call_func-trapjumps,d1
|
||||
cmp.w #2*19,d4
|
||||
beq.s .intisok
|
||||
.needint
|
||||
move.l #RTAREA_TRAPTASK,d0
|
||||
bsr.w getrtbase
|
||||
move.l (a0),d0
|
||||
beq.s .intisok
|
||||
; call func or lib, task needed
|
||||
move.l d0,a1
|
||||
move.b #$fe,TRAP_STATUS_STATUS(a5)
|
||||
move.l #$0100,d0
|
||||
jsr -$144(a6) ; Signal
|
||||
moveq #1,d0
|
||||
bra.s .exitactive
|
||||
.intisok
|
||||
add.w d1,a3
|
||||
movem.l 4(a4),a0-a2
|
||||
movem.l 4(a4),d0-d2
|
||||
movem.l (a4),a0-a2
|
||||
movem.l (a4),d0-d2
|
||||
jsr (a3)
|
||||
move.l d0,4(a4)
|
||||
move.b #1,TRAP_STATUS_STATUS(a5)
|
||||
move.l d0,(a4)
|
||||
moveq #0,d0
|
||||
.exitactive
|
||||
movem.l (sp)+,d1-d4/a1-a6
|
||||
bra.w .checkagain
|
||||
movem.l (sp)+,d1-d5/a1-a5
|
||||
rts
|
||||
|
||||
trapjumps:
|
||||
dc.w hw_multi-trapjumps; 0
|
||||
|
||||
1769
filesys_bootrom.cpp
1769
filesys_bootrom.cpp
File diff suppressed because it is too large
Load Diff
@ -247,12 +247,6 @@ static void get_prefetch_020 (void)
|
||||
return;
|
||||
printf ("\tregs.irc = %s (%d);\n", prefetch_word, m68k_pc_offset);
|
||||
}
|
||||
static void get_prefetch_020_0 (void)
|
||||
{
|
||||
if (!isprefetch020() || no_prefetch_ce020)
|
||||
return;
|
||||
printf ("\tregs.irc = %s (0);\n", prefetch_word);
|
||||
}
|
||||
static void get_prefetch_020_continue(void)
|
||||
{
|
||||
if (!isprefetch020())
|
||||
|
||||
167
hardfile.cpp
167
hardfile.cpp
@ -1137,16 +1137,25 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat
|
||||
return total;
|
||||
}
|
||||
|
||||
static int checkbounds (struct hardfiledata *hfd, uae_u64 offset, uae_u64 len)
|
||||
static int checkbounds (struct hardfiledata *hfd, uae_u64 offset, uae_u64 len, int mode)
|
||||
{
|
||||
uae_u64 max = hfd->virtsize;
|
||||
if (offset >= max || offset + len > max || (offset > 0xffffffff && (uae_s64)offset < 0)) {
|
||||
write_log (_T("UAEHF SCSI: out of bounds, %08X-%08X + %08X-%08X > %08X-%08X\n"),
|
||||
(uae_u32)(offset >> 32),(uae_u32)offset,(uae_u32)(len >> 32),(uae_u32)len,
|
||||
(uae_u32)(max >> 32),(uae_u32)max);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
if ((mode == 1 || mode == 2) && hfd->ci.badblock_num) {
|
||||
offset /= hfd->ci.blocksize;
|
||||
len /= hfd->ci.blocksize;
|
||||
for (int i = 0; i < hfd->ci.badblock_num; i++) {
|
||||
struct uaedev_badblock *bb = &hfd->ci.badblocks[i];
|
||||
if (offset + len >= bb->first && offset < bb->last)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_writeprotected(struct hardfiledata *hfd)
|
||||
@ -1230,6 +1239,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
|
||||
uae_u64 len, offset;
|
||||
int lr = 0, ls = 0;
|
||||
int chkerr;
|
||||
int scsi_len = -1;
|
||||
int status = 0;
|
||||
int lun;
|
||||
@ -1293,11 +1303,14 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
if (nodisk(hfd))
|
||||
goto nodisk;
|
||||
offset = get_scsi_6_offset(hfd, hdhfd, cmdbuf);
|
||||
if (offset == ~0)
|
||||
goto outofbounds;
|
||||
if (offset == ~0) {
|
||||
chkerr = 1;
|
||||
goto checkfail;
|
||||
}
|
||||
offset *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, hfd->ci.blocksize))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, hfd->ci.blocksize, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = 0;
|
||||
goto scsi_done;
|
||||
case 0x0c: /* INITIALIZE DRIVE CHARACTERISTICS */
|
||||
@ -1408,37 +1421,46 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
if (nodisk(hfd))
|
||||
goto nodisk;
|
||||
offset = get_scsi_6_offset(hfd, hdhfd, cmdbuf);
|
||||
if (offset == ~0)
|
||||
goto outofbounds;
|
||||
if (offset == ~0) {
|
||||
chkerr = 1;
|
||||
goto checkfail;
|
||||
}
|
||||
offset *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, hfd->ci.blocksize))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, hfd->ci.blocksize, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = 0;
|
||||
break;
|
||||
case 0x0b: /* SEEK (6) */
|
||||
if (nodisk (hfd))
|
||||
goto nodisk;
|
||||
offset = get_scsi_6_offset(hfd, hdhfd, cmdbuf);
|
||||
if (offset == ~0)
|
||||
goto outofbounds;
|
||||
if (offset == ~0) {
|
||||
chkerr = 1;
|
||||
goto checkfail;
|
||||
}
|
||||
offset *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, hfd->ci.blocksize))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, hfd->ci.blocksize, 3);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = 0;
|
||||
break;
|
||||
case 0x08: /* READ (6) */
|
||||
if (nodisk (hfd))
|
||||
goto nodisk;
|
||||
offset = get_scsi_6_offset(hfd, hdhfd, cmdbuf);
|
||||
if (offset == ~0)
|
||||
goto outofbounds;
|
||||
if (offset == ~0) {
|
||||
chkerr = 1;
|
||||
goto checkfail;
|
||||
}
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = cmdbuf[4];
|
||||
if (!len)
|
||||
len = 256;
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0x0f: /* WRITE SECTOR BUFFER */
|
||||
@ -1450,15 +1472,18 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
if (is_writeprotected(hfd))
|
||||
goto readprot;
|
||||
offset = get_scsi_6_offset(hfd, hdhfd, cmdbuf);
|
||||
if (offset == ~0)
|
||||
goto outofbounds;
|
||||
if (offset == ~0) {
|
||||
chkerr = 1;
|
||||
goto checkfail;
|
||||
}
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = cmdbuf[4];
|
||||
if (!len)
|
||||
len = 256;
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 2);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0x5a: // MODE SENSE(10)
|
||||
@ -1627,8 +1652,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
goto nodisk;
|
||||
offset = rl (cmdbuf + 2);
|
||||
offset *= hfd->ci.blocksize;
|
||||
if (!checkbounds (hfd, offset, hfd->ci.blocksize))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, hfd->ci.blocksize, 3);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = 0;
|
||||
break;
|
||||
case 0x28: /* READ (10) */
|
||||
@ -1638,8 +1664,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = rl (cmdbuf + 7 - 2) & 0xffff;
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds (hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0x2a: /* WRITE (10) */
|
||||
@ -1651,8 +1678,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = rl (cmdbuf + 7 - 2) & 0xffff;
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds (hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 2);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0x2f: /* VERIFY (10) */
|
||||
@ -1665,18 +1693,19 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = rl (cmdbuf + 7 - 2) & 0xffff;
|
||||
len *= hfd->ci.blocksize;
|
||||
uae_u8 *vb = xmalloc (uae_u8, hfd->ci.blocksize);
|
||||
if (checkbounds (hfd, offset, len)) {
|
||||
while (len > 0) {
|
||||
int readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize);
|
||||
if (readlen != hfd->ci.blocksize || memcmp (vb, scsi_data, hfd->ci.blocksize)) {
|
||||
xfree (vb);
|
||||
goto miscompare;
|
||||
}
|
||||
scsi_data += hfd->ci.blocksize;
|
||||
offset += hfd->ci.blocksize;
|
||||
len -= hfd->ci.blocksize;
|
||||
chkerr = checkbounds (hfd, offset, len, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
uae_u8 *vb = xmalloc(uae_u8, hfd->ci.blocksize);
|
||||
while (len > 0) {
|
||||
int readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize);
|
||||
if (readlen != hfd->ci.blocksize || memcmp (vb, scsi_data, hfd->ci.blocksize)) {
|
||||
xfree (vb);
|
||||
goto miscompare;
|
||||
}
|
||||
scsi_data += hfd->ci.blocksize;
|
||||
offset += hfd->ci.blocksize;
|
||||
len -= hfd->ci.blocksize;
|
||||
}
|
||||
xfree (vb);
|
||||
}
|
||||
@ -1695,8 +1724,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = rl (cmdbuf + 6);
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 1);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0xaa: /* WRITE (12) */
|
||||
@ -1708,8 +1738,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
||||
offset *= hfd->ci.blocksize;
|
||||
len = rl (cmdbuf + 6);
|
||||
len *= hfd->ci.blocksize;
|
||||
if (!checkbounds(hfd, offset, len))
|
||||
goto outofbounds;
|
||||
chkerr = checkbounds(hfd, offset, len, 2);
|
||||
if (chkerr)
|
||||
goto checkfail;
|
||||
scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
|
||||
break;
|
||||
case 0x37: /* READ DEFECT DATA */
|
||||
@ -1764,11 +1795,19 @@ errreq:
|
||||
s[12] = 0x24; /* ILLEGAL FIELD IN CDB */
|
||||
ls = 0x12;
|
||||
break;
|
||||
outofbounds:
|
||||
checkfail:
|
||||
status = 2; /* CHECK CONDITION */
|
||||
s[0] = 0x70;
|
||||
s[2] = 5; /* ILLEGAL REQUEST */
|
||||
s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */
|
||||
if (chkerr < 0) {
|
||||
s[2] = 5; /* ILLEGAL REQUEST */
|
||||
s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */
|
||||
} else {
|
||||
s[2] = 3; /* MEDIUM ERROR */
|
||||
if (chkerr == 1)
|
||||
s[12] = 0x11; /* Unrecovered Read Error */
|
||||
if (chkerr == 2)
|
||||
s[12] = 0x0c; /* Write Error */
|
||||
}
|
||||
ls = 0x12;
|
||||
break;
|
||||
miscompare:
|
||||
@ -1881,11 +1920,11 @@ static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct
|
||||
trap_set_bytes(ctx, scsi_sense + sd->sense_len, 0, scsi_sense_len - sd->sense_len);
|
||||
}
|
||||
}
|
||||
if (scsi_len < 0) {
|
||||
if (sd->data_len < 0) {
|
||||
put_long_host(scsicmd + 8, 0); /* scsi_Actual */
|
||||
ret = 20;
|
||||
} else {
|
||||
put_long_host(scsicmd + 8, scsi_len); /* scsi_Actual */
|
||||
put_long_host(scsicmd + 8, sd->data_len); /* scsi_Actual */
|
||||
}
|
||||
|
||||
trap_put_bytes(ctx, scsicmd, scsicmdaddr, sizeof scsicmd);
|
||||
@ -2102,6 +2141,21 @@ static void unaligned (int cmd, uae_u64 offset, uae_u64 len, int blocksize)
|
||||
blocksize);
|
||||
}
|
||||
|
||||
static bool isbadblock(struct hardfiledata *hfd, uae_u64 offset, uae_u64 len)
|
||||
{
|
||||
if (!hfd->ci.badblock_num)
|
||||
return false;
|
||||
offset /= hfd->ci.blocksize;
|
||||
len /= hfd->ci.blocksize;
|
||||
for (int i = 0; i < hfd->ci.badblock_num; i++) {
|
||||
struct uaedev_badblock *bb = &hfd->ci.badblocks[i];
|
||||
if (offset + len >= bb->first && offset < bb->last) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struct hardfileprivdata *hfpd, uae_u8 *iobuf, uaecptr request)
|
||||
{
|
||||
uae_u32 dataptr, offset, actual = 0, cmd;
|
||||
@ -2133,6 +2187,9 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
||||
outofbounds (cmd, offset, len, hfd->virtsize);
|
||||
goto bad_len;
|
||||
}
|
||||
if (isbadblock(hfd, offset, len)) {
|
||||
goto bad_block;
|
||||
}
|
||||
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset, len);
|
||||
break;
|
||||
|
||||
@ -2154,6 +2211,9 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
||||
outofbounds (cmd, offset64, len, hfd->virtsize);
|
||||
goto bad_len;
|
||||
}
|
||||
if (isbadblock(hfd, offset64, len)) {
|
||||
goto bad_block;
|
||||
}
|
||||
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset64, len);
|
||||
break;
|
||||
|
||||
@ -2178,6 +2238,9 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
||||
outofbounds (cmd, offset, len, hfd->virtsize);
|
||||
goto bad_len;
|
||||
}
|
||||
if (isbadblock(hfd, offset, len)) {
|
||||
goto bad_block;
|
||||
}
|
||||
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset, len);
|
||||
}
|
||||
break;
|
||||
@ -2205,6 +2268,9 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
||||
outofbounds (cmd, offset64, len, hfd->virtsize);
|
||||
goto bad_len;
|
||||
}
|
||||
if (isbadblock(hfd, offset64, len)) {
|
||||
goto bad_block;
|
||||
}
|
||||
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset64, len);
|
||||
}
|
||||
break;
|
||||
@ -2315,6 +2381,9 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
||||
}
|
||||
break;
|
||||
|
||||
bad_block:
|
||||
error = 45; // HFERR_BadStatus
|
||||
break;
|
||||
bad_command:
|
||||
error = IOERR_BADADDRESS;
|
||||
break;
|
||||
|
||||
@ -161,6 +161,12 @@ struct wh {
|
||||
#define BOOTPRI_NOAUTOMOUNT -129
|
||||
#define ISAUTOBOOT(ci) ((ci)->bootpri > BOOTPRI_NOAUTOBOOT)
|
||||
#define ISAUTOMOUNT(ci) ((ci)->bootpri > BOOTPRI_NOAUTOMOUNT)
|
||||
#define MAX_UAEDEV_BADBLOCKS 8
|
||||
struct uaedev_badblock
|
||||
{
|
||||
uae_u32 first;
|
||||
uae_u32 last;
|
||||
};
|
||||
struct uaedev_config_info {
|
||||
int type;
|
||||
TCHAR devname[MAX_DPATH];
|
||||
@ -198,6 +204,8 @@ struct uaedev_config_info {
|
||||
int forceload;
|
||||
int device_emu_unit;
|
||||
bool inject_icons;
|
||||
int badblock_num;
|
||||
struct uaedev_badblock badblocks[MAX_UAEDEV_BADBLOCKS];
|
||||
};
|
||||
|
||||
struct uaedev_config_data
|
||||
@ -254,6 +262,7 @@ struct chipset_refresh
|
||||
int index;
|
||||
bool locked;
|
||||
bool rtg;
|
||||
bool exit;
|
||||
int horiz;
|
||||
int vert;
|
||||
int lace;
|
||||
|
||||
183
inputdevice.cpp
183
inputdevice.cpp
@ -5034,6 +5034,7 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
|
||||
uae_u32 nmask = (buttonstate ? 1 : 0) << button;
|
||||
uae_u64 qualmask[MAX_INPUT_SUB_EVENT];
|
||||
bool qualonly;
|
||||
bool doit = true;
|
||||
|
||||
if (input_play && buttonstate)
|
||||
inprec_realtime ();
|
||||
@ -5065,93 +5066,101 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
|
||||
if (button >= ID_BUTTON_TOTAL)
|
||||
return;
|
||||
|
||||
getqualmask (qualmask, id, ID_BUTTON_OFFSET + button, &qualonly);
|
||||
|
||||
bool didcustom = false;
|
||||
|
||||
for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
|
||||
int sub = sublevdir[buttonstate == 0 ? 1 : 0][i];
|
||||
uae_u64 *flagsp = &id->flags[ID_BUTTON_OFFSET + button][sub];
|
||||
int evt = id->eventid[ID_BUTTON_OFFSET + button][sub];
|
||||
TCHAR *custom = id->custom[ID_BUTTON_OFFSET + button][sub];
|
||||
uae_u64 flags = flagsp[0];
|
||||
int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
|
||||
int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
|
||||
int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
|
||||
int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
|
||||
int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0;
|
||||
int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE;
|
||||
int state;
|
||||
|
||||
if (buttonstate < 0) {
|
||||
state = buttonstate;
|
||||
} else if (invert) {
|
||||
state = buttonstate ? 0 : 1;
|
||||
} else {
|
||||
state = buttonstate;
|
||||
}
|
||||
if (setmode) {
|
||||
if (state)
|
||||
state = setval;
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
}
|
||||
|
||||
setqualifiers (evt, state > 0);
|
||||
|
||||
if (qualonly)
|
||||
continue;
|
||||
|
||||
if (state < 0) {
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL))
|
||||
continue;
|
||||
handle_input_event (evt, 1, 1, 0, true, false);
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, 0, i);
|
||||
} else if (inverttoggle) {
|
||||
/* pressed = firebutton, not pressed = autofire */
|
||||
if (state) {
|
||||
queue_input_event (evt, NULL, -1, 0, 0, 1);
|
||||
handle_input_event (evt, 1, 1, 0, true, false);
|
||||
} else {
|
||||
handle_input_event (evt, 1, 1, autofire, true, false);
|
||||
}
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
} else if (toggle) {
|
||||
if (!state)
|
||||
continue;
|
||||
if (omask & mask)
|
||||
continue;
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL))
|
||||
continue;
|
||||
*flagsp ^= ID_FLAG_TOGGLED;
|
||||
int toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
|
||||
handle_input_event (evt, toggled, 1, autofire, true, false);
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, toggled, qualmask, autofire, i);
|
||||
} else {
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL)) {
|
||||
if (!state && !(flags & ID_FLAG_CANRELEASE)) {
|
||||
if (!invert)
|
||||
continue;
|
||||
} else if (state) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!state)
|
||||
*flagsp &= ~ID_FLAG_CANRELEASE;
|
||||
else
|
||||
*flagsp |= ID_FLAG_CANRELEASE;
|
||||
if ((omask ^ nmask) & mask) {
|
||||
handle_input_event (evt, state, 1, autofire, true, false);
|
||||
if (state)
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
}
|
||||
}
|
||||
if (currprefs.input_tablet == TABLET_REAL && mousehack_alive()) {
|
||||
// mouse driver injects all buttons when tablet mode
|
||||
if (id == &mice[0])
|
||||
doit = false;
|
||||
}
|
||||
|
||||
if (!didcustom)
|
||||
queue_input_event (-1, NULL, -1, 0, 0, 1);
|
||||
if (doit) {
|
||||
getqualmask (qualmask, id, ID_BUTTON_OFFSET + button, &qualonly);
|
||||
|
||||
bool didcustom = false;
|
||||
|
||||
for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
|
||||
int sub = sublevdir[buttonstate == 0 ? 1 : 0][i];
|
||||
uae_u64 *flagsp = &id->flags[ID_BUTTON_OFFSET + button][sub];
|
||||
int evt = id->eventid[ID_BUTTON_OFFSET + button][sub];
|
||||
TCHAR *custom = id->custom[ID_BUTTON_OFFSET + button][sub];
|
||||
uae_u64 flags = flagsp[0];
|
||||
int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
|
||||
int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
|
||||
int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
|
||||
int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
|
||||
int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0;
|
||||
int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE;
|
||||
int state;
|
||||
|
||||
if (buttonstate < 0) {
|
||||
state = buttonstate;
|
||||
} else if (invert) {
|
||||
state = buttonstate ? 0 : 1;
|
||||
} else {
|
||||
state = buttonstate;
|
||||
}
|
||||
if (setmode) {
|
||||
if (state)
|
||||
state = setval;
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
}
|
||||
|
||||
setqualifiers (evt, state > 0);
|
||||
|
||||
if (qualonly)
|
||||
continue;
|
||||
|
||||
if (state < 0) {
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL))
|
||||
continue;
|
||||
handle_input_event (evt, 1, 1, 0, true, false);
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, 0, i);
|
||||
} else if (inverttoggle) {
|
||||
/* pressed = firebutton, not pressed = autofire */
|
||||
if (state) {
|
||||
queue_input_event (evt, NULL, -1, 0, 0, 1);
|
||||
handle_input_event (evt, 1, 1, 0, true, false);
|
||||
} else {
|
||||
handle_input_event (evt, 1, 1, autofire, true, false);
|
||||
}
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
} else if (toggle) {
|
||||
if (!state)
|
||||
continue;
|
||||
if (omask & mask)
|
||||
continue;
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL))
|
||||
continue;
|
||||
*flagsp ^= ID_FLAG_TOGGLED;
|
||||
int toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
|
||||
handle_input_event (evt, toggled, 1, autofire, true, false);
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, toggled, qualmask, autofire, i);
|
||||
} else {
|
||||
if (!checkqualifiers (evt, flags, qualmask, NULL)) {
|
||||
if (!state && !(flags & ID_FLAG_CANRELEASE)) {
|
||||
if (!invert)
|
||||
continue;
|
||||
} else if (state) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!state)
|
||||
*flagsp &= ~ID_FLAG_CANRELEASE;
|
||||
else
|
||||
*flagsp |= ID_FLAG_CANRELEASE;
|
||||
if ((omask ^ nmask) & mask) {
|
||||
handle_input_event (evt, state, 1, autofire, true, false);
|
||||
if (state)
|
||||
didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!didcustom)
|
||||
queue_input_event (-1, NULL, -1, 0, 0, 1);
|
||||
}
|
||||
|
||||
if (id2 && ((omask ^ nmask) & mask)) {
|
||||
if (buttonstate)
|
||||
@ -8135,7 +8144,7 @@ void setmousestate (int mouse, int axis, int data, int isabs)
|
||||
oldm_p = &oldm_axis[mouse][axis];
|
||||
if (!isabs) {
|
||||
// eat relative movements while in mousehack mode
|
||||
if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive ())
|
||||
if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive () && axis < 2)
|
||||
return;
|
||||
*oldm_p = *mouse_p;
|
||||
*mouse_p += data;
|
||||
@ -8150,7 +8159,7 @@ void setmousestate (int mouse, int axis, int data, int isabs)
|
||||
lastmy = data;
|
||||
if (axis)
|
||||
mousehack_helper (mice2[mouse].buttonmask);
|
||||
if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive ())
|
||||
if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive () && axis < 2)
|
||||
return;
|
||||
}
|
||||
v = (int)d;
|
||||
|
||||
@ -818,7 +818,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
|
||||
a |= (uae_s64)m68k_dreg (regs, extra & 7) << 32;
|
||||
}
|
||||
|
||||
if (a == 0x8000000000000000 && src == ~0u) {
|
||||
if ((uae_u64)a == 0x8000000000000000UL && src == ~0u) {
|
||||
SET_VFLG (1);
|
||||
SET_NFLG (1);
|
||||
SET_CFLG (0);
|
||||
|
||||
@ -2942,7 +2942,7 @@ static void D3D_render2 (void)
|
||||
LPDIRECT3DTEXTURE9 srctex = texture;
|
||||
UINT uPasses, uPass;
|
||||
|
||||
if (!isd3d ())
|
||||
if (!isd3d () || !texture)
|
||||
return;
|
||||
|
||||
hr = d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0);
|
||||
|
||||
@ -509,9 +509,9 @@ BEGIN
|
||||
PUSHBUTTON "Swap ports [] Swap ports 1 and 2.",IDC_SWAP,45,100,78,14
|
||||
LTEXT "Emulated parallel port joystick adapter",IDC_STATIC,10,124,179,15,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_PORT2_JOYS,45,142,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Remap [] Remap Parallel port joystick port 1 configurarion.",IDC_PORT2_REMAP,352,159,36,14
|
||||
PUSHBUTTON "Remap / Test [] Remap or test Parallel port joystick port 1 configurarion.",IDC_PORT2_REMAP,310,159,78,14
|
||||
COMBOBOX IDC_PORT3_JOYS,45,178,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Remap [] Remap Parallel port joystick port 2 configurarion.",IDC_PORT3_REMAP,352,194,36,14
|
||||
PUSHBUTTON "Remap / Test [] Remap or test Parallel port joystick port 2 configurarion.",IDC_PORT3_REMAP,310,194,78,14
|
||||
GROUPBOX "Mouse extra settings",IDC_STATIC,1,219,393,68
|
||||
RTEXT "Mouse speed:",IDC_STATIC,19,237,82,10,SS_CENTERIMAGE
|
||||
EDITTEXT IDC_INPUTSPEEDM,115,237,25,13,ES_NUMBER
|
||||
|
||||
@ -20,12 +20,12 @@
|
||||
#define LANG_DLL_FULL_VERSION_MATCH 1
|
||||
|
||||
#if WINUAEPUBLICBETA
|
||||
#define WINUAEBETA _T("8")
|
||||
#define WINUAEBETA _T("9")
|
||||
#else
|
||||
#define WINUAEBETA _T("")
|
||||
#endif
|
||||
|
||||
#define WINUAEDATE MAKEBD(2016, 3, 5)
|
||||
#define WINUAEDATE MAKEBD(2016, 3, 19)
|
||||
|
||||
//#define WINUAEEXTRA _T("AmiKit Preview")
|
||||
//#define WINUAEEXTRA _T("Amiga Forever Edition")
|
||||
|
||||
@ -1,4 +1,20 @@
|
||||
|
||||
Beta 9:
|
||||
|
||||
- Fixed swapped audio channels if stereo separation was set (b1 cleanup missed code path)
|
||||
- Fixed uaehf.device SCSI emulation sense data possible crash/wrong status. (trap update related)
|
||||
- 32M UAE RTG board was always address space aligned. It is wrong in UAE mapping mode.
|
||||
- Only swallow hardware horizontal and vertical mouse movement when in mouse driver mode, not mouse wheel.
|
||||
- Improved programmed refresh rate hsync start and end validation to prevent crashes if weird mode is set.
|
||||
(BoggleDop / Sanity)
|
||||
- Added hardfile virtual bad block support. uaehf.device and hardware SCSI emulation only. Create geometry text file
|
||||
(<name of hardfile.hdf>.geo) in same directory as hardfile, add badblocks=<blocks> line. (<blocks> can be range, 10-100
|
||||
or single value or multiple ranges/values, for example 10-100,200,1000-20000) Max 8 bad block values/ranges supported.
|
||||
Error is returned if block in badblock range is attempted to be read or written.
|
||||
- OS4.x UAE trap mode now uses hybrid busy wait mode. Performance has improved again, directory filesystem speed is now
|
||||
fully usable and uaegfx is also noticeably faster.
|
||||
- UAE indirect trap stability updates.
|
||||
|
||||
Beta 8:
|
||||
|
||||
- Game Ports joystick type was always empty (undefined).
|
||||
|
||||
192
sana2.cpp
192
sana2.cpp
@ -246,14 +246,20 @@ static struct s2devstruct *gets2devstruct (int unit)
|
||||
return &devst[unit];
|
||||
}
|
||||
|
||||
static struct priv_s2devstruct *getps2devstruct(TrapContext *ctx, uaecptr request)
|
||||
static struct priv_s2devstruct *getps2devstruct(TrapContext *ctx, uae_u8 *iobuf, uaecptr request)
|
||||
{
|
||||
int i = trap_get_long(ctx, request + 24);
|
||||
if (i < 0 || i >= MAX_OPEN_DEVICES || pdevst[i].inuse == 0) {
|
||||
write_log (_T("%s: corrupt iorequest %08X %d\n"), SANA2NAME, request, i);
|
||||
int idx;
|
||||
|
||||
if (iobuf) {
|
||||
idx = get_long_host(iobuf + 24);
|
||||
} else {
|
||||
idx = trap_get_long(ctx, request + 24);
|
||||
}
|
||||
if (idx < 0 || idx >= MAX_OPEN_DEVICES || pdevst[idx].inuse == 0) {
|
||||
write_log (_T("%s: corrupt iorequest %08X %d\n"), SANA2NAME, request, idx);
|
||||
return 0;
|
||||
}
|
||||
return &pdevst[i];
|
||||
return &pdevst[idx];
|
||||
}
|
||||
|
||||
static void *dev_thread (void *devs);
|
||||
@ -271,7 +277,7 @@ static int start_thread (struct s2devstruct *dev)
|
||||
static uae_u32 REGPARAM2 dev_close_2 (TrapContext *ctx)
|
||||
{
|
||||
uae_u32 request = trap_get_areg(ctx, 1);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, NULL, request);
|
||||
struct s2devstruct *dev;
|
||||
|
||||
if (!pdev) {
|
||||
@ -505,11 +511,11 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *ctx)
|
||||
/* buffermanagement */
|
||||
trap_put_long(ctx, ioreq + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4 + 4 + 4, pdev->tempbuf);
|
||||
}
|
||||
dev->exclusive = flags & SANA2OPF_MINE;
|
||||
dev->exclusive = (flags & SANA2OPF_MINE) != 0;
|
||||
dev->opencnt++;
|
||||
trap_put_word(ctx, trap_get_areg(ctx, 6) + 32, trap_get_word(ctx, trap_get_areg(ctx, 6) + 32) + 1);
|
||||
trap_put_byte(ctx, ioreq + 31, 0);
|
||||
trap_put_byte(ctx, ioreq + 8, 7);
|
||||
trap_put_byte(ctx, ioreq + 8, 7); // NT_REPLYMSG
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -825,20 +831,6 @@ static int handleread (TrapContext *ctx, struct priv_s2devstruct *pdev, struct s
|
||||
memcpy(dstaddr, d, ADDR_SIZE);
|
||||
memcpy(srcaddr, d + ADDR_SIZE, ADDR_SIZE);
|
||||
|
||||
/* drop if CMD_READ and multicast with unknown address */
|
||||
if (cmd == CMD_READ && ismulticast(dstaddr)) {
|
||||
uae_u64 mac64 = addrto64(dstaddr);
|
||||
/* multicast */
|
||||
struct mcast *mc = dev->mc;
|
||||
while (mc) {
|
||||
if (mac64 >= mc->start && mac64 <= mc->end)
|
||||
break;
|
||||
mc = mc->next;
|
||||
}
|
||||
if (!mc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
put_long_host(request + 32 + 4, type);
|
||||
if (pdev->tracks[type]) {
|
||||
pdev->bytesreceived += len;
|
||||
@ -859,14 +851,36 @@ static int handleread (TrapContext *ctx, struct priv_s2devstruct *pdev, struct s
|
||||
}
|
||||
put_long_host(request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2, len);
|
||||
|
||||
if (cmd == CMD_READ) {
|
||||
if (pdev->packetfilter && packetfilter (ctx, pdev->packetfilter, arequest, data2) == 0)
|
||||
/* drop if CMD_READ and multicast with unknown address */
|
||||
if (cmd == CMD_READ && ismulticast(dstaddr)) {
|
||||
uae_u64 mac64 = addrto64(dstaddr);
|
||||
/* multicast */
|
||||
struct mcast *mc = dev->mc;
|
||||
while (mc) {
|
||||
if (mac64 >= mc->start && mac64 <= mc->end)
|
||||
break;
|
||||
mc = mc->next;
|
||||
}
|
||||
if (!mc) {
|
||||
if (log_net)
|
||||
write_log(_T("-> multicast filter rejected, CMD_READ, REQ=%08X LEN=%d\n"), arequest, len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == CMD_READ) {
|
||||
if (pdev->packetfilter && packetfilter (ctx, pdev->packetfilter, arequest, data2) == 0) {
|
||||
if (log_net)
|
||||
write_log(_T("-> PacketFilter() rejected, CMD_READ, REQ=%08X LEN=%d\n"), arequest, len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copytobuff (ctx, data2, data, len, pdev->copytobuff)) {
|
||||
put_long_host(request + 32, S2WERR_BUFF_ERROR);
|
||||
put_byte_host(request + 31, S2ERR_NO_RESOURCES);
|
||||
if (log_net)
|
||||
write_log(_T("-> CopyToBuff() rejected, CMD_READ, REQ=%08X LEN=%d\n"), arequest, len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -911,7 +925,7 @@ static void uaenet_gotdata (void *devv, const uae_u8 *d, int len)
|
||||
|
||||
static struct s2packet *createwritepacket(TrapContext *ctx, uae_u8 *request, uaecptr arequest)
|
||||
{
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
uae_u8 flags = get_byte_host(request + 30);
|
||||
uae_u32 datalength = get_long_host(request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2);
|
||||
uaecptr data = get_long_host(request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4);
|
||||
@ -922,8 +936,11 @@ static struct s2packet *createwritepacket(TrapContext *ctx, uae_u8 *request, uae
|
||||
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
if (!copyfrombuff (ctx, data, pdev->tempbuf, datalength, pdev->copyfrombuff))
|
||||
if (!copyfrombuff (ctx, data, pdev->tempbuf, datalength, pdev->copyfrombuff)) {
|
||||
if (log_net)
|
||||
write_log(_T("-> CopyFromBuff() rejected, CMD_READ, REQ=%08X LEN=%d\n"), arequest, datalength);
|
||||
return NULL;
|
||||
}
|
||||
s2p = xcalloc (struct s2packet, 1);
|
||||
s2p->data = xmalloc (uae_u8, pdev->td->mtu + ETH_HEADER_SIZE + 2);
|
||||
if (flags & SANA2IOF_RAW) {
|
||||
@ -961,7 +978,7 @@ static int uaenet_getdata(void *devv, uae_u8 *d, int *len)
|
||||
int command = get_word_host(request + 28);
|
||||
uae_u32 packettype = get_long_host(request + 32 + 4);
|
||||
if (command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) {
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(dev->ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(dev->ctx, request, arequest);
|
||||
struct asyncreq *ars2p = dev->s2p;
|
||||
while (ars2p) {
|
||||
if (ars2p->arequest == arequest) {
|
||||
@ -1026,7 +1043,7 @@ static void flush(TrapContext *ctx, struct priv_s2devstruct *pdev)
|
||||
dev = gets2devstruct (pdev->unit);
|
||||
ar = dev->ar;
|
||||
while (ar) {
|
||||
if (!ar->ready && getps2devstruct(ctx, ar->arequest) == pdev) {
|
||||
if (!ar->ready && getps2devstruct(ctx, ar->request, ar->arequest) == pdev) {
|
||||
ar->ready = 1;
|
||||
do_abort_async(ctx, dev, ar->request, ar->arequest);
|
||||
}
|
||||
@ -1036,7 +1053,7 @@ static void flush(TrapContext *ctx, struct priv_s2devstruct *pdev)
|
||||
|
||||
static int dev_do_io_2 (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *request, uaecptr arequest, int quick)
|
||||
{
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
|
||||
uae_u8 flags = get_byte_host(request + 30);
|
||||
uae_u32 command = get_word_host(request + 28);
|
||||
@ -1054,10 +1071,10 @@ static int dev_do_io_2 (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *reque
|
||||
|
||||
if (log_net)
|
||||
write_log (_T("S2: IO=%08x %p C=%02d T=%04X S=%02X%02X%02X%02X%02X%02X D=%02X%02X%02X%02X%02X%02X L=%d D=%08X SD=%08X BM=%08X\n"),
|
||||
arequest, request, command, packettype,
|
||||
get_byte_host(srcaddr + 0), get_byte_host(srcaddr + 1), get_byte_host(srcaddr + 2), get_byte_host(srcaddr + 3), get_byte_host(srcaddr + 4), get_byte_host(srcaddr + 5),
|
||||
get_byte_host(dstaddr + 0), get_byte_host(dstaddr + 1), get_byte_host(dstaddr + 2), get_byte_host(dstaddr + 3), get_byte_host(dstaddr + 4), get_byte_host(dstaddr + 5),
|
||||
datalength, data, statdata, buffermgmt);
|
||||
arequest, request, command, packettype,
|
||||
get_byte_host(srcaddr + 0), get_byte_host(srcaddr + 1), get_byte_host(srcaddr + 2), get_byte_host(srcaddr + 3), get_byte_host(srcaddr + 4), get_byte_host(srcaddr + 5),
|
||||
get_byte_host(dstaddr + 0), get_byte_host(dstaddr + 1), get_byte_host(dstaddr + 2), get_byte_host(dstaddr + 3), get_byte_host(dstaddr + 4), get_byte_host(dstaddr + 5),
|
||||
datalength, data, statdata, buffermgmt);
|
||||
|
||||
if (command == CMD_READ || command == S2_READORPHAN || command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) {
|
||||
if (!pdev->copyfrombuff || !pdev->copytobuff) {
|
||||
@ -1136,22 +1153,19 @@ static int dev_do_io_2 (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *reque
|
||||
|
||||
case S2_DEVICEQUERY:
|
||||
{
|
||||
uae_u8 statbuf[34];
|
||||
int size = trap_get_long(ctx, statdata);
|
||||
if (size > 30)
|
||||
size = 30;
|
||||
trap_put_long(ctx, statdata + 4, size);
|
||||
if (size >= 12)
|
||||
trap_put_long(ctx, statdata + 8, 0);
|
||||
if (size >= 16)
|
||||
trap_put_long(ctx, statdata + 12, 0);
|
||||
if (size >= 18)
|
||||
trap_put_word(ctx, statdata + 16, ADDR_SIZE * 8);
|
||||
if (size >= 22)
|
||||
trap_put_long(ctx, statdata + 18, dev->td->mtu);
|
||||
if (size >= 26)
|
||||
trap_put_long(ctx, statdata + 22, 10000000);
|
||||
if (size >= 30)
|
||||
trap_put_long(ctx, statdata + 26, S2WireType_Ethernet);
|
||||
if (size > 34)
|
||||
size = 34;
|
||||
put_long_host(statbuf + 4 , size);
|
||||
put_long_host(statbuf + 8, 0);
|
||||
put_long_host(statbuf + 12, 0);
|
||||
put_word_host(statbuf + 16, ADDR_SIZE * 8);
|
||||
put_long_host(statbuf + 18, dev->td->mtu);
|
||||
put_long_host(statbuf + 22, 10000000);
|
||||
put_long_host(statbuf + 26, S2WireType_Ethernet);
|
||||
put_long_host(statbuf + 30, 1514);
|
||||
trap_put_bytes(ctx, statbuf + 4, statdata + 4, size - 4);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1295,9 +1309,9 @@ end:
|
||||
|
||||
static int dev_do_io (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *request, uaecptr arequest, int quick)
|
||||
{
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
uae_u32 command = get_word_host(request + 28);
|
||||
uaecptr data = get_long_host(request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4);
|
||||
uae_u16 len = get_word_host(request + 0x12);
|
||||
|
||||
put_byte_host(request + 31, 0);
|
||||
if (!pdev) {
|
||||
@ -1313,7 +1327,7 @@ static int dev_do_io (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *request
|
||||
trap_put_long(ctx, data + 12, nscmd_cmd);
|
||||
put_long_host(request + 32, 16); /* io_actual */
|
||||
return 0;
|
||||
} else if (get_word_host(request + 0x12) < SANA2_IOREQSIZE) {
|
||||
} else if (len < SANA2_IOREQSIZE) {
|
||||
put_byte_host(request + 31, IOERR_BADLENGTH);
|
||||
return 0;
|
||||
}
|
||||
@ -1324,13 +1338,13 @@ static int dev_can_quick (uae_u32 command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case NSCMD_DEVICEQUERY:
|
||||
case S2_DEVICEQUERY:
|
||||
case S2_CONFIGINTERFACE:
|
||||
case S2_GETSTATIONADDRESS:
|
||||
case S2_TRACKTYPE:
|
||||
case S2_UNTRACKTYPE:
|
||||
return 0;
|
||||
case NSCMD_DEVICEQUERY:
|
||||
case S2_DEVICEQUERY:
|
||||
case S2_CONFIGINTERFACE:
|
||||
case S2_GETSTATIONADDRESS:
|
||||
case S2_TRACKTYPE:
|
||||
case S2_UNTRACKTYPE:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1341,13 +1355,39 @@ static int dev_canquick (TrapContext *ctx, struct s2devstruct *dev, uae_u8 *requ
|
||||
return dev_can_quick (command);
|
||||
}
|
||||
|
||||
static void storerequest(TrapContext *ctx, uae_u8 *src, uaecptr dst)
|
||||
{
|
||||
uae_u32 cmd = get_word_host(src + 28);
|
||||
uae_u16 len = get_word_host(src + 18);
|
||||
if (len < 30)
|
||||
return;
|
||||
len -= 30;
|
||||
src += 30;
|
||||
dst += 30;
|
||||
if (cmd == S2_BROADCAST || cmd == S2_MULTICAST || cmd == S2_READORPHAN || cmd == CMD_WRITE || cmd == CMD_READ || cmd == S2_GETSTATIONADDRESS) {
|
||||
// Copy:
|
||||
// io_Flags, ioError
|
||||
// ios2_WireError, ios2_PacketType
|
||||
// ios2_SrcAddr, ios2_DstAddr
|
||||
// ios2_DataLength
|
||||
if (len > 1 + 1 + 4 + 4 + 2 * SANA2_MAX_ADDR_BYTES + 4)
|
||||
len = 1 + 1 + 4 + 4 + 2 * SANA2_MAX_ADDR_BYTES + 4;
|
||||
trap_put_bytes(ctx, src, dst, len);
|
||||
} else {
|
||||
// Copy:
|
||||
// io_Flags, ioError
|
||||
// ios2_WireError
|
||||
trap_put_bytes(ctx, src, dst, 1 + 1 + 4);
|
||||
}
|
||||
}
|
||||
|
||||
static uae_u32 REGPARAM2 dev_beginio (TrapContext *ctx)
|
||||
{
|
||||
uae_u32 err = 0;
|
||||
uae_u32 arequest = trap_get_areg(ctx, 1);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
uae_u8 *request = xmalloc(uae_u8, SANA2_IOREQSIZE);
|
||||
trap_get_bytes(ctx, request, arequest, SANA2_IOREQSIZE);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
|
||||
uae_u8 flags = get_byte_host(request + 30);
|
||||
int command = get_word_host(request + 28);
|
||||
@ -1381,12 +1421,12 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *ctx)
|
||||
} else {
|
||||
if (command == S2_BROADCAST) {
|
||||
uae_u8 *dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES;
|
||||
put_byte_host(dstaddr + 0, 0xff);
|
||||
put_byte_host(dstaddr + 1, 0xff);
|
||||
put_byte_host(dstaddr + 2, 0xff);
|
||||
put_byte_host(dstaddr + 3, 0xff);
|
||||
put_byte_host(dstaddr + 4, 0xff);
|
||||
put_byte_host(dstaddr + 5, 0xff);
|
||||
put_byte_host(dstaddr + 0, 0xff);
|
||||
put_byte_host(dstaddr + 1, 0xff);
|
||||
put_byte_host(dstaddr + 2, 0xff);
|
||||
put_byte_host(dstaddr + 3, 0xff);
|
||||
put_byte_host(dstaddr + 4, 0xff);
|
||||
put_byte_host(dstaddr + 5, 0xff);
|
||||
}
|
||||
s2p = createwritepacket(ctx, request, arequest);
|
||||
if (s2p) {
|
||||
@ -1401,7 +1441,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *ctx)
|
||||
}
|
||||
}
|
||||
put_byte_host(request + 30, get_byte_host(request + 30) & ~1);
|
||||
trap_put_bytes(ctx, request + 8, arequest + 8, SANA2_IOREQSIZE - 8);
|
||||
storerequest(ctx, request, arequest);
|
||||
uae_sem_wait(&pipe_sem);
|
||||
trap_set_background(ctx);
|
||||
write_comm_pipe_pvoid(&dev->requests, ctx, 0);
|
||||
@ -1411,7 +1451,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
err:
|
||||
trap_put_bytes(ctx, request + 8, arequest + 8, SANA2_IOREQSIZE - 8);
|
||||
storerequest(ctx, request, arequest);
|
||||
xfree(request);
|
||||
return err;
|
||||
}
|
||||
@ -1435,15 +1475,15 @@ static void *dev_thread (void *devs)
|
||||
write_log (_T("%s: dev_thread killed\n"), getdevname ());
|
||||
return 0;
|
||||
}
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, iobuf, request);
|
||||
asyncreq *ar = get_async_request (dev, request, 1);
|
||||
if (ar) {
|
||||
trap_put_bytes(ctx, ar->request + 8, request + 8, SANA2_IOREQSIZE - 8);
|
||||
storerequest(ctx, ar->request, request);
|
||||
uae_ReplyMsg (request);
|
||||
release_async_request (dev, request);
|
||||
rem_async_packet (dev, request);
|
||||
} else if (dev_do_io(ctx, dev, iobuf, request, 0) == 0) {
|
||||
trap_put_bytes(ctx, iobuf + 8, request + 8, SANA2_IOREQSIZE - 8);
|
||||
storerequest(ctx, iobuf, request);
|
||||
uae_ReplyMsg (request);
|
||||
rem_async_packet (dev, request);
|
||||
} else {
|
||||
@ -1476,7 +1516,7 @@ static uae_u32 REGPARAM2 dev_abortio (TrapContext *ctx)
|
||||
{
|
||||
uae_u8 err = 0;
|
||||
uae_u32 request = trap_get_areg(ctx, 1);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, NULL, request);
|
||||
struct s2devstruct *dev;
|
||||
|
||||
if (!pdev) {
|
||||
@ -1526,7 +1566,7 @@ static int uaenet_int_handler2(TrapContext *ctx)
|
||||
if (command == CMD_READ) {
|
||||
uae_u32 packettype = get_long_host(request + 32 + 4);
|
||||
if (packettype == type || (packettype <= 1500 && type <= 1500)) {
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
if (pdev && pdev->tmp == 0) {
|
||||
if (handleread (ctx, pdev, dev, request, arequest, p->data, p->len, command)) {
|
||||
if (log_net)
|
||||
@ -1544,8 +1584,6 @@ static int uaenet_int_handler2(TrapContext *ctx)
|
||||
freepacket(p);
|
||||
return -1;
|
||||
} else {
|
||||
if (log_net)
|
||||
write_log (_T("-> %p PacketFilter() rejected, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len);
|
||||
pdev->tmp = -1;
|
||||
}
|
||||
}
|
||||
@ -1561,7 +1599,7 @@ static int uaenet_int_handler2(TrapContext *ctx)
|
||||
uae_u8 *request = ar->request;
|
||||
int command = get_word_host(request + 28);
|
||||
if (command == S2_READORPHAN) {
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
if (pdev && pdev->tmp <= 0) {
|
||||
if (log_net)
|
||||
write_log (_T("-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n"), p, arequest, p->len);
|
||||
@ -1613,7 +1651,7 @@ static int uaenet_int_handler2(TrapContext *ctx)
|
||||
uae_u8 *request = ar->request;
|
||||
int command = get_word_host(request + 28);
|
||||
if (command == S2_ONLINE) {
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
dev->packetsreceived = 0;
|
||||
dev->packetssent = 0;
|
||||
dev->baddata = 0;
|
||||
@ -1653,7 +1691,7 @@ static int uaenet_int_handler2(TrapContext *ctx)
|
||||
uae_sem_post(&pipe_sem);
|
||||
return -1;
|
||||
} else {
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, arequest);
|
||||
struct priv_s2devstruct *pdev = getps2devstruct(ctx, request, arequest);
|
||||
if (pdev) {
|
||||
dev->flush_timeout--;
|
||||
if (dev->flush_timeout <= 0) {
|
||||
|
||||
124
traps.cpp
124
traps.cpp
@ -10,11 +10,11 @@
|
||||
* Copyright 1996 Ed Hanway
|
||||
*/
|
||||
|
||||
#define NEW_TRAP_DEBUG 0
|
||||
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
#define NEW_TRAP_DEBUG 0
|
||||
|
||||
#include "options.h"
|
||||
#include "memory.h"
|
||||
#include "custom.h"
|
||||
@ -23,6 +23,7 @@
|
||||
#include "autoconf.h"
|
||||
#include "traps.h"
|
||||
#include "uae.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
* Traps are the mechanism via which 68k code can call emulator code
|
||||
@ -232,6 +233,8 @@ struct TrapContext
|
||||
int tcnt;
|
||||
TRAP_CALLBACK callback;
|
||||
void *callback_ud;
|
||||
int trap_mode;
|
||||
int trap_slot;
|
||||
};
|
||||
|
||||
static void copytocpucontext(struct TrapCPUContext *cpu)
|
||||
@ -310,6 +313,8 @@ static smp_comm_pipe trap_thread_pipe[TRAP_THREADS];
|
||||
static uae_thread_id trap_thread_id[TRAP_THREADS];
|
||||
static volatile uae_atomic trap_thread_index;
|
||||
static volatile int hardware_trap_kill[TRAP_THREADS];
|
||||
static volatile bool trap_in_use[TRAP_THREADS];
|
||||
static volatile bool trap_in_use2[TRAP_THREADS];
|
||||
static volatile int trap_cnt;
|
||||
volatile int trap_mode;
|
||||
|
||||
@ -319,17 +324,21 @@ static void hardware_trap_ack(TrapContext *ctx)
|
||||
uae_u8 *status = ctx->host_trap_status;
|
||||
uaecptr addr = ctx->amiga_trap_status;
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("%d: A%d\n"), ctx->tcnt, ctx->tindex);
|
||||
#endif
|
||||
|
||||
// ack call_hardware_trap
|
||||
uaecptr task = get_long_host(data + RTAREA_TRAP_DATA_TASKWAIT);
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("TRAP SLOT %d: ACK. TASK = %08x\n"), ctx->trap_slot, task);
|
||||
#endif
|
||||
|
||||
put_byte_host(status + 2, 0xff);
|
||||
if (task) {
|
||||
if (task && trap_mode == 1) {
|
||||
atomic_or(&uae_int_requested, 0x4000);
|
||||
set_special_exter(SPCFLAG_UAEINT);
|
||||
}
|
||||
if (!trap_in_use[ctx->trap_slot])
|
||||
write_log(_T("TRAP SLOT %d ACK WIIHOUT ALLOCATION!\n"));
|
||||
trap_in_use[ctx->trap_slot] = false;
|
||||
xfree(ctx);
|
||||
}
|
||||
|
||||
@ -341,6 +350,11 @@ static void *hardware_trap_thread(void *arg)
|
||||
if (!ctx)
|
||||
break;
|
||||
|
||||
if (trap_in_use[ctx->trap_slot]) {
|
||||
write_log(_T("TRAP SLOT %d ALREADY IN USE!\n"));
|
||||
}
|
||||
trap_in_use[ctx->trap_slot] = true;
|
||||
|
||||
uae_u8 *data = ctx->host_trap_data;
|
||||
uae_u8 *status = ctx->host_trap_status;
|
||||
ctx->tindex = tid;
|
||||
@ -352,31 +366,36 @@ static void *hardware_trap_thread(void *arg)
|
||||
}
|
||||
put_long_host(status + RTAREA_TRAP_STATUS_SECOND, 0);
|
||||
|
||||
int trap_num = get_word_host(status);
|
||||
struct Trap *trap = &traps[trap_num];
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
if (_tcscmp(trap->name, _T("exter_int_helper")))
|
||||
write_log(_T("%d: T%d,%d,%08x\n"), ctx->tcnt, tid, trap_num, trap->addr);
|
||||
//if (_tcscmp(trap->name, _T("exter_int_helper")))
|
||||
write_log(_T("TRAP SLOT %d: NUM %d\n"), ctx->trap_slot, trap_num);
|
||||
#endif
|
||||
|
||||
uae_u32 ret;
|
||||
struct Trap *trap = NULL;
|
||||
|
||||
if (ctx->trap_done)
|
||||
write_log(_T("hardware_trap_thread #1: trap_done set!"));
|
||||
|
||||
if (ctx->callback) {
|
||||
ret = ctx->callback(ctx, ctx->callback_ud);
|
||||
} else {
|
||||
int trap_num = get_word_host(status);
|
||||
trap = &traps[trap_num];
|
||||
ret = trap->handler(ctx);
|
||||
}
|
||||
|
||||
if (ctx->trap_done)
|
||||
write_log(_T("hardware_trap_thread #2: trap_done set!"));
|
||||
|
||||
if (!ctx->trap_background) {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
uae_u32 v = ctx->saved_regs.regs[i];
|
||||
put_long_host(data + 4 + i * 4, v);
|
||||
}
|
||||
if ((trap->flags & TRAPFLAG_NO_RETVAL) == 0) {
|
||||
if (trap && (trap->flags & TRAPFLAG_NO_RETVAL) == 0) {
|
||||
put_long_host(data + 4, ret);
|
||||
}
|
||||
|
||||
hardware_trap_ack(ctx);
|
||||
} else {
|
||||
ctx->trap_done = true;
|
||||
@ -404,7 +423,7 @@ void trap_background_set_complete(TrapContext *ctx)
|
||||
|
||||
void trap_dos_active(void)
|
||||
{
|
||||
trap_mode = 1;
|
||||
trap_mode = 0;
|
||||
}
|
||||
|
||||
void call_hardware_trap(uae_u8 *host_base, uaecptr amiga_base, int slot)
|
||||
@ -414,11 +433,14 @@ void call_hardware_trap(uae_u8 *host_base, uaecptr amiga_base, int slot)
|
||||
ctx->amiga_trap_data = amiga_base + RTAREA_TRAP_DATA + slot * RTAREA_TRAP_DATA_SLOT_SIZE;
|
||||
ctx->host_trap_status = host_base + RTAREA_TRAP_STATUS + slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
ctx->amiga_trap_status = amiga_base + RTAREA_TRAP_STATUS + slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
ctx->trap_mode = trap_mode;
|
||||
ctx->trap_slot = slot;
|
||||
uae_u32 idx = atomic_inc(&trap_thread_index) & (RTAREA_TRAP_DATA_NUM - 1);
|
||||
write_comm_pipe_pvoid(&trap_thread_pipe[idx], ctx, 1);
|
||||
}
|
||||
|
||||
extern uae_sem_t hardware_trap_event[];
|
||||
extern uae_sem_t hardware_trap_event2[];
|
||||
|
||||
static struct TrapContext outtrap[RTAREA_TRAP_DATA_SEND_NUM];
|
||||
static volatile uae_atomic outtrap_alloc[RTAREA_TRAP_DATA_SEND_NUM];
|
||||
@ -432,6 +454,7 @@ TrapContext *alloc_host_main_trap_context(void)
|
||||
sleep_millis(1);
|
||||
}
|
||||
TrapContext *ctx = &outtrap[trap_slot - RTAREA_TRAP_DATA_NUM];
|
||||
ctx->trap_slot = trap_slot;
|
||||
return ctx;
|
||||
} else {
|
||||
return NULL;
|
||||
@ -446,35 +469,50 @@ void free_host_trap_context(TrapContext *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static uae_u32 call_hardware_trap_back_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1, uae_u32 p2, uae_u32 p3, uae_u32 p4)
|
||||
static uae_u32 call_hardware_trap_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1, uae_u32 p2, uae_u32 p3, uae_u32 p4)
|
||||
{
|
||||
int trap_slot = ((ctx->amiga_trap_data & 0xffff) - RTAREA_TRAP_DATA) / RTAREA_TRAP_DATA_SLOT_SIZE;
|
||||
uae_u8 *data = ctx->host_trap_data + RTAREA_TRAP_DATA_SECOND;
|
||||
uae_u8 *status = ctx->host_trap_status + RTAREA_TRAP_STATUS_SECOND;
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("%d: B%dS%d\n"), ctx->tcnt, cmd, trap_slot);
|
||||
write_log(_T("TRAP BACK SLOT %d: CMD=%d P=%08x %08x %08x %08x TASK=%08x\n"),
|
||||
trap_slot, cmd, p1, p2, p3, p4, get_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_TASKWAIT));
|
||||
#endif
|
||||
|
||||
if (trap_slot != ctx->trap_slot)
|
||||
write_log(_T("Trap trap slot mismatch %d <> %d!\n"), trap_slot, ctx->trap_slot);
|
||||
|
||||
if (trap_in_use2[trap_slot])
|
||||
write_log(_T("Trap slot %d already in use2!\n"), trap_slot);
|
||||
trap_in_use2[trap_slot] = true;
|
||||
|
||||
put_long_host(data + 4, p1);
|
||||
put_long_host(data + 8, p2);
|
||||
put_long_host(data + 12, p3);
|
||||
put_long_host(data + 16, p4);
|
||||
put_word_host(status, cmd);
|
||||
|
||||
atomic_inc(&hwtrap_waiting);
|
||||
atomic_or(&uae_int_requested, 0x2000);
|
||||
set_special_exter(SPCFLAG_UAEINT);
|
||||
|
||||
volatile uae_u8 *d = status + 3;
|
||||
|
||||
*d = 0xff;
|
||||
if (ctx->trap_mode == 2) {
|
||||
*d = 0xfe;
|
||||
// signal rtarea_bget wait
|
||||
uae_sem_post(&hardware_trap_event2[trap_slot]);
|
||||
} else if (ctx->trap_mode == 0) {
|
||||
*d = 0xfe;
|
||||
} else {
|
||||
atomic_inc(&hwtrap_waiting);
|
||||
atomic_or(&uae_int_requested, 0x2000);
|
||||
set_special_exter(SPCFLAG_UAEINT);
|
||||
*d = 0xff;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (hardware_trap_kill[trap_slot] < 0)
|
||||
return 0;
|
||||
uae_u8 v = *d;
|
||||
if (v == 0x01 || v == 0x02)
|
||||
if (v == 0x01 || v == 0x02 || v == 0x03)
|
||||
break;
|
||||
if (hardware_trap_kill[trap_slot] == 0) {
|
||||
hardware_trap_kill[trap_slot] = 2;
|
||||
@ -489,20 +527,19 @@ static uae_u32 call_hardware_trap_back_back(TrapContext *ctx, uae_u16 cmd, uae_u
|
||||
// get result
|
||||
uae_u32 v = get_long_host(data + 4);
|
||||
|
||||
if (!trap_in_use2[trap_slot])
|
||||
write_log(_T("Trap slot %d in use2 unexpected release!\n"), trap_slot);
|
||||
trap_in_use2[trap_slot] = false;
|
||||
|
||||
put_long_host(status, 0);
|
||||
|
||||
#if NEW_TRAP_DEBUG
|
||||
write_log(_T("%d: =%08x\n"), ctx->tcnt, v, hwtrap_waiting);
|
||||
write_log(_T("TRAP BACK SLOT %d: RET = %08x TASK = %08x\n"), trap_slot, v, get_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_TASKWAIT));
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static uae_u32 call_hardware_trap_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1, uae_u32 p2, uae_u32 p3, uae_u32 p4)
|
||||
{
|
||||
return call_hardware_trap_back_back(ctx, cmd, p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
// Executes trap from C-code
|
||||
void trap_callback(TRAP_CALLBACK cb, void *ud)
|
||||
{
|
||||
@ -513,10 +550,12 @@ void trap_callback(TRAP_CALLBACK cb, void *ud)
|
||||
ctx->amiga_trap_data = rtarea_base + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
|
||||
ctx->host_trap_status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
ctx->amiga_trap_status = rtarea_base + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
|
||||
ctx->trap_mode = 1;
|
||||
ctx->trap_slot = trap_slot;
|
||||
|
||||
// Set status to allocated, we are skipping hwtrap_entry()
|
||||
put_long_host(ctx->host_trap_status + 4, 0x00000000);
|
||||
put_long_host(ctx->host_trap_status, 0x00000080);
|
||||
put_long_host(ctx->host_trap_status + 0, 0x00000080);
|
||||
|
||||
ctx->callback = cb;
|
||||
ctx->callback_ud = ud;
|
||||
@ -535,6 +574,7 @@ TrapContext *alloc_host_thread_trap_context(void)
|
||||
ctx->amiga_trap_data = rtarea_base + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
|
||||
ctx->host_trap_status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
ctx->amiga_trap_status = rtarea_base + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
|
||||
ctx->trap_mode = 1;
|
||||
|
||||
// Set status to allocated, we are skipping hwtrap_entry()
|
||||
put_long_host(ctx->host_trap_status + 4, 0x00000000);
|
||||
@ -1036,7 +1076,7 @@ uae_u8 trap_get_byte(TrapContext *ctx, uaecptr addr)
|
||||
|
||||
void trap_put_bytes(TrapContext *ctx, const void *haddrp, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
uae_u8 *haddr = (uae_u8*)haddrp;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
@ -1061,7 +1101,7 @@ void trap_put_bytes(TrapContext *ctx, const void *haddrp, uaecptr addr, int cnt)
|
||||
}
|
||||
void trap_get_bytes(TrapContext *ctx, void *haddrp, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
uae_u8 *haddr = (uae_u8*)haddrp;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
@ -1086,7 +1126,7 @@ void trap_get_bytes(TrapContext *ctx, void *haddrp, uaecptr addr, int cnt)
|
||||
}
|
||||
void trap_put_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
while (cnt > 0) {
|
||||
@ -1108,7 +1148,7 @@ void trap_put_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt)
|
||||
}
|
||||
void trap_get_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
while (cnt > 0) {
|
||||
@ -1130,7 +1170,7 @@ void trap_get_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt)
|
||||
}
|
||||
void trap_put_words(TrapContext *ctx, uae_u16 *haddr, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
while (cnt > 0) {
|
||||
@ -1152,7 +1192,7 @@ void trap_put_words(TrapContext *ctx, uae_u16 *haddr, uaecptr addr, int cnt)
|
||||
}
|
||||
void trap_get_words(TrapContext *ctx, uae_u16 *haddr, uaecptr addr, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
while (cnt > 0) {
|
||||
@ -1258,7 +1298,7 @@ int trap_get_bstr(TrapContext *ctx, uae_u8 *haddr, uaecptr addr, int maxlen)
|
||||
|
||||
void trap_set_longs(TrapContext *ctx, uaecptr addr, uae_u32 v, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
call_hardware_trap_back(ctx, TRAPCMD_SET_LONGS, addr, v, cnt, 0);
|
||||
@ -1271,7 +1311,7 @@ void trap_set_longs(TrapContext *ctx, uaecptr addr, uae_u32 v, int cnt)
|
||||
}
|
||||
void trap_set_words(TrapContext *ctx, uaecptr addr, uae_u16 v, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
call_hardware_trap_back(ctx, TRAPCMD_SET_WORDS, addr, v, cnt, 0);
|
||||
@ -1284,7 +1324,7 @@ void trap_set_words(TrapContext *ctx, uaecptr addr, uae_u16 v, int cnt)
|
||||
}
|
||||
void trap_set_bytes(TrapContext *ctx, uaecptr addr, uae_u8 v, int cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
if (cnt <= 0)
|
||||
return;
|
||||
if (trap_is_indirect_null(ctx)) {
|
||||
call_hardware_trap_back(ctx, TRAPCMD_SET_BYTES, addr, v, cnt, 0);
|
||||
@ -1387,6 +1427,8 @@ void trap_multi(TrapContext *ctx, struct trapmd *data, int items)
|
||||
|
||||
void trap_memcpyha_safe(TrapContext *ctx, uaecptr dst, const uae_u8 *src, int size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return;
|
||||
if (trap_is_indirect()) {
|
||||
trap_put_bytes(ctx, src, dst, size);
|
||||
} else {
|
||||
@ -1395,6 +1437,8 @@ void trap_memcpyha_safe(TrapContext *ctx, uaecptr dst, const uae_u8 *src, int si
|
||||
}
|
||||
void trap_memcpyah_safe(TrapContext *ctx, uae_u8 *dst, uaecptr src, int size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return;
|
||||
if (trap_is_indirect()) {
|
||||
trap_get_bytes(ctx, dst, src, size);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user