This commit is contained in:
Toni Wilen 2016-03-19 18:41:35 +02:00
parent ac2410d9ef
commit d3d6eb18b2
18 changed files with 1638 additions and 1253 deletions

8
ar.cpp
View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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 {

View File

@ -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;

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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())

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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")

View File

@ -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
View File

@ -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
View File

@ -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 {