uae_u8 cycle_line[256];
#endif
-static uae_u32 bpl1dat, bpl5dat;
+static uae_u16 bplxdat[8];
static uae_s16 bpl1mod, bpl2mod;
static uaecptr bplpt[8], f_bplpt[8];
#endif
/* Expansions from bplcon0/bplcon1. */
-static int toscr_res, toscr_nr_planes, fetchwidth;
+static int toscr_res, toscr_nr_planes, toscr_nr_planes2, fetchwidth;
static int toscr_delay1x, toscr_delay2x, toscr_delay1, toscr_delay2;
/* The number of bits left from the last fetched words.
curr_color_changes[next_color_change].regno = -1;
}
+// OCS/ECS, lores, 7 planes = 4 "real" planes + BPL5DAT and BPL6DAT as 5th and 6th plane
+STATIC_INLINE int isocs7planes (void)
+{
+ return !(currprefs.chipset_mask & CSMASK_AGA) && f_bplcon0_res == 0 && f_bplcon0_planes == 7;
+}
+
static uae_u16 tmp_bplcon0, tmp_fmode;
STATIC_INLINE fetch_bpl_params (void)
{
f_fetch_modulo_cycle = t_fetchunit - f_fetchstart;
if (toscr_nr_planes < f_bplcon0_planes_limit)
toscr_nr_planes = f_bplcon0_planes_limit;
+ if (isocs7planes ()) {
+ if (toscr_nr_planes2 < 6)
+ toscr_nr_planes2 = 6;
+ } else {
+ toscr_nr_planes2 = toscr_nr_planes;
+ }
toscr_res = f_bplcon0_res;
}
{
toscr_res = f_bplcon0_res;
toscr_nr_planes = f_bplcon0_planes_limit;
+ toscr_nr_planes2 = f_bplcon0_planes;
compute_toscr_delay_1 ();
}
switch (fm)
{
case 0:
- fetched[nr] = last_custom_value = chipmem_agnus_wget (p);
+ fetched[nr] = bplxdat[nr] = last_custom_value = chipmem_agnus_wget (p);
break;
#ifdef AGA
case 1:
mod = bpl1mod;
bplpt[nr] += mod;
}
+ } else if (isocs7planes ()) {
+ fetched[nr] = bplxdat[nr];
}
if (nr == 0)
fetch_state = fetch_was_plane0;
static void update_toscr_planes (void)
{
- if (toscr_nr_planes > thisline_decision.nr_planes) {
+ if (toscr_nr_planes2 > thisline_decision.nr_planes) {
int j;
- for (j = thisline_decision.nr_planes; j < toscr_nr_planes; j++)
+ for (j = thisline_decision.nr_planes; j < toscr_nr_planes2; j++)
clear_fetchbuffer ((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs);
#if 0
if (thisline_decision.nr_planes > 0)
- printf ("Planes from %d to %d\n", thisline_decision.nr_planes, toscr_nr_planes);
+ printf ("Planes from %d to %d\n", thisline_decision.nr_planes, toscr_nr_planes2);
#endif
- thisline_decision.nr_planes = toscr_nr_planes;
+ thisline_decision.nr_planes = toscr_nr_planes2;
}
}
int i;
uae_u32 mask = 0xFFFF >> (16 - nbits);
- for (i = 0; i < toscr_nr_planes; i += 2) {
+ for (i = 0; i < toscr_nr_planes2; i += 2) {
outword[i] <<= nbits;
outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask;
todisplay[i][0] <<= nbits;
}
- for (i = 1; i < toscr_nr_planes; i += 2) {
+ for (i = 1; i < toscr_nr_planes2; i += 2) {
outword[i] <<= nbits;
outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask;
todisplay[i][0] <<= nbits;
if (off1 == 3)
off1 = 2;
offs -= off1 * 32;
- for (i = 0; i < toscr_nr_planes; i += 2) {
+ for (i = 0; i < toscr_nr_planes2; i += 2) {
uae_u32 t0 = todisplay[i][off1];
uae_u32 t1 = todisplay[i][off1 + 1];
uae_u64 t = (((uae_u64)t1) << 32) | t0;
if (off1 == 3)
off1 = 2;
offs -= off1 * 32;
- for (i = 1; i < toscr_nr_planes; i += 2) {
+ for (i = 1; i < toscr_nr_planes2; i += 2) {
uae_u32 t0 = todisplay[i][off1];
uae_u32 t1 = todisplay[i][off1 + 1];
uae_u64 t = (((uae_u64)t1) << 32) | t0;
return;
curr_diagram_change = -1;
- toscr_nr_planes = 0;
+ toscr_nr_planes = toscr_nr_planes2 = 0;
thisline_decision.bplres = t_bplcon0_res;
thisline_decision.nr_planes = 0;
//write_log ("%d:%d:BPL%dPTL %08X\n", hpos, vpos, num, v);
}
+static int isehb (uae_u16 bplcon0, uae_u16 bplcon2)
+{
+ int bplehb;
+ if (currprefs.chipset_mask & CSMASK_AGA)
+ bplehb = (bplcon0 & 0x7010) == 0x6000 && !(bplcon2 & 0x200);
+ else if (currprefs.chipset_mask & CSMASK_ECS_DENISE)
+ bplehb = (bplcon0 & 0xFC00) == 0x6000 && !(bplcon2 & 0x200);
+ else
+ bplehb = (bplcon0 & 0xFC00) == 0x6000 && !currprefs.cs_denisenoehb;
+ return bplehb;
+}
static void BPLCON0 (int hpos, uae_u16 v)
{
if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE))
decide_fetch (hpos);
decide_blitter (hpos);
+ // fake unused 0x0080 bit as an EHB bit (see below)
+ if (isehb (v, bplcon2))
+ v |= 0x80;
+
+ if ((bplcon0 & (0x800 | 0x400 | 0x80)) != (v & (0x800 | 0x400 | 0x80))) // HAM/EBH/DPF change is instant
+ record_register_change (hpos, 0x100, (bplcon0 & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80)));
bplcon0 = v;
#ifdef ECS_DENISE
curr_diagram_change = -1;
if (fetch_state == fetch_started && diwstate == DIW_waiting_stop) {
- curr_diagram_change = hpos + f_fm_maxplane - (fetch_cycle & f_fetchstart_mask);
+ curr_diagram_change = hpos - 2 + f_fm_maxplane - (fetch_cycle & f_fetchstart_mask);
} else {
curr_diagram = cycle_diagram_table[fetchmode][t_bplcon0_res][t_bplcon0_planes_limit];
}
bpl2mod = v;
}
-/* needed in special OCS/ECS "7-plane" mode. not yet implemented. */
+/* needed in special OCS/ECS "7-plane" mode. */
static void BPL5DAT (int hpos, uae_u16 v)
{
decide_line (hpos);
- bpl5dat = v;
+ bplxdat[4] = v;
+}
+static void BPL6DAT (int hpos, uae_u16 v)
+{
+ decide_line (hpos);
+ bplxdat[5] = v;
}
STATIC_INLINE void BPL1DAT (int hpos, uae_u16 v)
{
decide_line (hpos);
- bpl1dat = v;
+ bplxdat[0] = v;
maybe_first_bpl1dat (hpos);
}
calcdiw ();
}
+static void FNULL (uae_u16 v)
+{
+
+}
+
static void BLTADAT (uae_u16 v)
{
maybe_blit (current_hpos(), 0);
case 0x110: BPL1DAT (hpos, value); break;
case 0x118: BPL5DAT (hpos, value); break;
+ case 0x11A: BPL6DAT (hpos, value); break;
case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
#ifdef AGA
case 0x1FC: FMODE (value); break;
#endif
+ case 0x1FE: FNULL (value); break;
/* writing to read-only register causes read access */
default:
bplcon4 = RW; /* 10C BPLCON4 */
clxcon2 = RW; /* 10E CLXCON2* */
for(i = 0; i < 8; i++)
- RW; /* BPLXDAT */
+ bplxdat[i] = RW; /* BPLXDAT */
for(i = 0; i < 32; i++)
current_colors.color_regs_ecs[i] = RW; /* 180 COLORxx */
htotal = RW; /* 1C0 HTOTAL */
SW (bplcon4); /* 10C BPLCON4 */
SW (clxcon2); /* 10E CLXCON2 */
for (i = 0;i < 8; i++)
- SW (0); /* 110 BPLxDAT */
+ SW (bplxdat[i]); /* 110 BPLxDAT */
if (full) {
for (i = 0; i < 8; i++) {
SL (spr[i].pt); /* 120-13E SPRxPT */
static int real_playfield_start, real_playfield_end;
static int pixels_offset;
-static int src_pixel;
+static int src_pixel, ham_src_pixel;
/* How many pixels in window coordinates which are to the left of the left border. */
static int unpainted;
static int seen_sprites;
int linetoscr_diw_start = dp_for_drawing->diwfirstword;
int linetoscr_diw_end = dp_for_drawing->diwlastword;
+ res_shift = lores_shift - bplres;
+
if (dip_for_drawing->nr_sprites == 0) {
if (linetoscr_diw_start < native_ddf_left)
linetoscr_diw_start = native_ddf_left;
playfield_start = linetoscr_diw_start;
playfield_end = linetoscr_diw_end;
+ unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start;
+ ham_src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window (playfield_start - native_ddf_left);
+ unpainted = res_shift_from_window (unpainted);
+
if (playfield_start < visible_left_border)
playfield_start = visible_left_border;
if (playfield_start > visible_right_border)
sprite_first_x = MAX_PIXELS_PER_LINE - 1;
/* Now, compute some offsets. */
- res_shift = lores_shift - bplres;
ddf_left -= DISPLAY_LEFT_SHIFT;
pixels_offset = MAX_PIXELS_PER_LINE - (ddf_left << bplres);
ddf_left <<= bplres;
-
- unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start;
- src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window (playfield_start - native_ddf_left + unpainted);
+ src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window (playfield_start - native_ddf_left);
seen_sprites = 0;
if (dip_for_drawing->nr_sprites == 0)
{
}
-static unsigned int ham_lastcolor;
-
static int ham_decode_pixel;
+static unsigned int ham_lastcolor;
/* Decode HAM in the invisible portion of the display (left of VISIBLE_LEFT_BORDER),
but don't draw anything in. This is done to prepare HAM_LASTCOLOR for later,
when decode_ham runs. */
static void init_ham_decoding (void)
{
- int unpainted_amiga = res_shift_from_window (unpainted);
- ham_decode_pixel = src_pixel;
+ int unpainted_amiga = unpainted;
+
+ ham_decode_pixel = ham_src_pixel;
ham_lastcolor = color_reg_get (&colors_for_drawing, 0);
if (!bplham) {
if (bplres > 0)
can_use_lores = 0;
- if (currprefs.chipset_mask & CSMASK_AGA)
- bplehb = (dp_for_drawing->bplcon0 & 0x7010) == 0x6000 && !(dp_for_drawing->bplcon2 & 0x200);
- else if (currprefs.chipset_mask & CSMASK_ECS_DENISE)
- bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000 && !(dp_for_drawing->bplcon2 & 0x200);
- else
- bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000 && !currprefs.cs_denisenoehb;
-
+ bplehb = (dp_for_drawing->bplcon0 & 0x80) == 0x80;
plf1pri = dp_for_drawing->bplcon2 & 7;
plf2pri = (dp_for_drawing->bplcon2 >> 3) & 7;
plf_sprite_mask = 0xFFFF0000 << (4 * plf2pri);
static uae_u32 vhd_checksum (uae_u8 *p, int offset)
{
int i;
- uae_u32 sum, psum;
+ uae_u32 sum;
sum = 0;
for (i = 0; i < 512; i++) {
if (offset >= 0 && i >= offset && i < offset + 4)
continue;
- psum = sum;
- if ((sum += p[i]) < psum)
- sum++;
+ sum += p[i];
}
return ~sum;
}
batsize &= ~511;
ret = 0;
b = NULL;
- zf = zfile_fopen (name, "w");
+ zf = zfile_fopen (name, "wb");
if (!zf)
goto end;
b = xcalloc (512 + 1024 + batsize + 512, 1);
zfile_fwrite (b, 1024, 1, zf);
// bat
- memset (b, 0xff, batsize);
+ memset (b, 0, batsize);
+ memset (b, 0xff, batentrysize * 4);
zfile_fwrite (b, batsize, 1, zf);
ret = 1;
#define DUNUSED(x)
#define D
#define bug write_log
-#define MMUEX 0x12345678
+#define MMUEX 0x4d4d5520
#define TRY(x) __try
#define CATCH(x) __except(GetExceptionCode() == MMUEX)
#define THROW(x) RaiseException(MMUEX,EXCEPTION_NONCONTINUABLE,0,NULL)
#endif
uae_u8 nr_planes;
uae_u8 bplres;
- unsigned int ham_seen:1;
- unsigned int ham_at_start:1;
+ unsigned int ham_seen;
+ unsigned int ham_at_start;
};
/* Anything related to changes in hw registers during the DDF for one
int m68k_speed;
int cpu_model;
+ int mmu_model;
int cpu060_revision;
int fpu_model;
int fpu_revision;
int win32_soundcard;
int win32_norecyclebin;
int win32_specialkey;
+ int win32_guikey;
int win32_kbledmode;
int curses_reverse_video;
-extern int createIPC(void);
-extern void closeIPC(void);
-extern int checkIPC(struct uae_prefs*);
-extern void *geteventhandleIPC(void);
+
+#define COMPIPENAME "WinUAE_COM"
+
+extern void *createIPC(const char *name, int);
+extern void closeIPC(void*);
+extern int checkIPC(void*,struct uae_prefs*);
+extern void *geteventhandleIPC(void*);
+extern int sendBinIPC(void*, uae_u8 *msg, int len);
+extern int sendIPC(void*, char *msg);
+extern int isIPC (const char *pipename);
void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc)
{
#if 0
- if (1 || nr < 24)
+ //if (nr < 24)
+ if (nr >= 24 + 8)
write_log ("exception %d %08X %08X (%04X %04X)\n",
nr, oldpc, m68k_getpc (regs), intena, intreq);
#endif
if (!hdc) {
hr = IDirect3DDevice9_GetBackBuffer (d3ddev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &bb);
if (FAILED (hr)) {
- write_log ("failed to create backbuffer: %s\n", D3D_ErrorString (hr));
+ write_log ("IDirect3DDevice9_GetBackBuffer() failed: %s\n", D3D_ErrorString (hr));
return 0;
}
- if (IDirect3DSurface9_GetDC (bb, &hdc) == D3D_OK)
+ hr = IDirect3DSurface9_GetDC (bb, &hdc);
+ if (SUCCEEDED (hr))
return hdc;
+ write_log ("IDirect3DSurface9_GetDC() failed: %s\n", D3D_ErrorString (hr));
return 0;
}
IDirect3DSurface9_ReleaseDC (bb, hdc);
int DirectDraw_SurfaceLock (void)
{
int ok;
- if (getlocksurface () == NULL)
+ LPDIRECTDRAWSURFACE7 surf;
+
+ surf = getlocksurface ();
+ if (surf == NULL)
+ return 0;
+ if (IDirectDrawSurface7_IsLost (surf) == DDERR_SURFACELOST)
return 0;
if (dxdata.lockcnt > 0)
return 1;
}
void DirectDraw_SurfaceUnlock (void)
{
+ if (dxdata.lockcnt < 0)
+ write_log ("DirectDraw_SurfaceUnlock negative lock count %d!\n", dxdata.lockcnt);
if (dxdata.lockcnt == 0)
return;
dxdata.lockcnt--;
+++ /dev/null
- SECTION code,code
-; This file can be translated with A68k or PhxAss and then linked with BLink
-; to produce an Amiga executable. Make sure it does not contain any
-; relocations, then run it through the filesys.sh script
-;
-; Patrick: It also works with SAS/C asm+slink, but I had to remove
-; the .l from jsr.l and jmp.l.
-; Toni Wilen: modified SECTION, compiles now with AsmOne and clones(?)
-; Removed absolute RT_AREA references
-; 2002.08.06 RDB automount/autoboot support (Toni Wilen)
-; 2002.09.11 KS1.3 RDB support (TW)
-; 200?.??.?? Picasso96 vblank hack (TW)
-; 2006.03.04 Mousehack code integrated (TW)
-; 2006.18.07 FileSystem.resource find routine access fault fixed (TW)
-; 2007.03.30 mousehack do not start multiple times anymore (TW)
-; 2007.06.15 uninitialized variable in memory type selection fixed (stupid me) (TW)
-; 2007.08.09 started implementing removable drive support (TW)
-
-AllocMem = -198
-FreeMem = -210
-
-; don't forget filesys.c! */
-PP_MAXSIZE = 4 * 96
-PP_FSSIZE = 400
-PP_FSPTR = 404
-PP_FSRES = 408
-PP_EXPLIB = 412
-PP_FSHDSTART = 416
-PP_TOTAL = (PP_FSHDSTART+140)
-
-NOTIFY_CLASS = $40000000
-NOTIFY_CODE = $1234
-NRF_SEND_MESSAGE = 1
-NRF_SEND_SIGNAL = 2
-NRF_WAIT_REPLY = 8
-NRF_NOTIFY_INITIAL = 16
-NRF_MAGIC = $80000000
-
- dc.l 16
-our_seglist:
- dc.l 0 ;/* NextSeg */
-start:
- bra filesys_mainloop
- dc.l make_dev-start
- dc.l filesys_init-start
- dc.l exter_server-start
- dc.l bootcode-start
- dc.l setup_exter-start
-
- dc.l p96vsyncfix1-start
- dc.l mousehack_x-start
-
-bootcode:
- lea.l doslibname(pc),a1
- jsr -96(a6) ; FindResident
- move.l d0,a0
- move.l 22(a0),d0
- move.l d0,a0
- jsr (a0)
- rts
-
-filesys_init:
- movem.l d0-d7/a0-a6,-(sp)
- move.l 4.w,a6
- move.w #$FFFC,d0 ; filesys base
- bsr getrtbase
- move.l (a0),a5
- lea.l explibname(pc),a1 ; expansion lib name
- moveq #36,d0
- moveq #0,d5
- jsr -552(a6) ; OpenLibrary
- tst.l d0
- bne.b FSIN_explibok
- lea.l explibname(pc),a1 ; expansion lib name
- moveq #0,d0
- moveq #1,d5
- jsr -552(a6) ; OpenLibrary
-FSIN_explibok:
- move.l d0,a4
- move.l #PP_TOTAL,d0
- moveq #1,d1 ; MEMF_PUBLIC
- jsr AllocMem(a6)
- move.l d0,a3 ; param packet
- move.l a4,PP_EXPLIB(a3)
-
- moveq #0,d6
-FSIN_init_units:
- cmp.l $10c(a5),d6
- bcc.b FSIN_units_ok
- move.l d6,-(sp)
-FSIN_nextsub:
- moveq #1,d7
- move.l a3,-(sp)
- move.l a3,a0
- bsr.w make_dev
- move.l (sp)+,a3
- cmp.l #-2,d0
- beq.s FSIN_nomoresub
- swap d6
- addq.w #1,d6
- swap d6
- bra.s FSIN_nextsub
-FSIN_nomoresub:
- move.l (sp)+,d6
- addq.w #1,d6
- bra.b FSIN_init_units
-
-FSIN_units_ok:
- move.l 4.w,a6
- move.l a4,a1
- jsr -414(a6) ; CloseLibrary
-
-; move.w #$FF80,d0
-; bsr.w getrtbase
-; jsr (a0)
-; jsr -$0078(a6) ; Disable
-; lea 322(a6),a0 ; MemHeader
-;FSIN_scanchip:
-; move.l (a0),a0 ; first MemList
-; tst.l (a0)
-; beq.s FSIN_scandone
-; move.w 14(a0),d1 ; attributes
-; and #2,d1 ; MEMF_CHIP?
-; beq.s FSIN_scanchip
-; sub.l 24(a0),d0 ; did KS detect all chip?
-; bmi.s FSIN_scandone
-; beq.s FSIN_scandone
-; ; add the missing piece
-; add.l d0,24(a0) ; mh_Upper
-; add.l d0,28(a0) ; mh_Free
-; add.l d0,62(a6) ; MaxLocMem
-; ; we still need to update last node's free space
-; move.l 16(a0),a0 ; mh_First
-;FSIN_chiploop2
-; tst.l (a0)
-; beq.s FSIN_chiploop
-; move.l (a0),a0
-; bra.s FSIN_chiploop2
-;FSIN_chiploop:
-; add.l d0,4(a0)
-;FSIN_scandone:
-; jsr -$007e(a6) ; Enable
-
- ; add >2MB chip RAM to memory list
- move.w #$FF80,d0
- bsr.w getrtbase
- jsr (a0)
- moveq.l #3,d1
- moveq.l #-10,d2
- move.l #$200000,a0
- sub.l a0,d0
- bcs.b FSIN_chip_done
- beq.b FSIN_chip_done
- moveq.l #0,d4
- move.l d4,a1
- jsr -618(a6) ; AddMemList
-FSIN_chip_done
-
- movem.l (sp)+,d0-d7/a0-a6
-general_ret:
- rts
-
-exter_data:
-exter_server:
- movem.l a2,-(sp)
- move.w #$FF50,d0 ; exter_int_helper
- bsr.w getrtbase
- moveq.l #0,d0
- jsr (a0)
- tst.l d0
- beq.w exter_server_exit
- ; This is the hard part - we have to send some messages.
- move.l 4.w,a6
-EXTS_loop:
- move.w #$FF50,d0 ; exter_int_helper
- bsr.w getrtbase
- moveq.l #2,d0
- jsr (a0)
- cmp.w #1,d0
- blt.b EXTS_done
- bgt.b EXTS_signal_reply
- jsr -366(a6) ; PutMsg
- bra.b EXTS_loop
-EXTS_signal_reply:
- cmp.w #2,d0
- bgt.b EXTS_reply
- move.l d1,d0
- jsr -$144(a6) ; Signal
- bra.b EXTS_loop
-EXTS_reply:
- cmp.w #3,d0
- bgt.b EXTS_cause
- jsr -$17a(a6) ; ReplyMsg
- bra.b EXTS_loop
-EXTS_cause:
- cmp.w #4,d0
- bgt.b EXTS_notificationhack
- jsr -$b4(a6) ; Cause
- bra.b EXTS_loop
-EXTS_notificationhack:
- cmp.w #5,d0
- bgt.b EXTS_done
- movem.l a0-a1,-(sp)
- moveq #38,d0
- move.l #65536+1,d1
- jsr AllocMem(a6)
- movem.l (sp)+,a0-a1
- move.l d0,a2
- move.b #8,8(a2)
- move.l a0,14(a2)
- move.w #38,18(a2)
- move.l #NOTIFY_CLASS,20(a2)
- move.w #NOTIFY_CODE,24(a2)
- move.l a1,26(a2)
- move.l 16(a1),a0
- move.l a2,a1
- jsr -366(a6) ; PutMsg
- bra.w EXTS_loop
-EXTS_done:
- move.w #$FF50,d0 ;exter_int_helper
- bsr.w getrtbase
- moveq.l #4,d0
- jsr (a0)
- moveq.l #1,d0 ; clear Z - it was for us.
-exter_server_exit:
- movem.l (sp)+,a2
- rts
-
-setup_exter:
- movem.l d0-d1/a0-a1,-(sp)
- moveq.l #26,d0
- move.l #$10001,d1
- jsr AllocMem(a6)
- move.l d0,a1
- lea.l exter_name(pc),a0
- move.l a0,10(a1)
- lea.l exter_data(pc),a0
- move.l a0,14(a1)
- lea.l exter_server(pc),a0
- move.l a0,18(a1)
- move.w #$0214,8(a1)
- moveq.l #3,d0
- jsr -168(a6) ; AddIntServer
- movem.l (sp)+,d0-d1/a0-a1
- rts
-
-addfs: ; a0 = first hunk, a1 = parmpacket
- movem.l d0-d1/a0-a3/a6,-(sp)
- move.l 4.w,a6
- move.l a0,a2
- move.l a1,a3
- move.l #62+128,d0 ; sizeof(FileSysEntry) + patchflags;
- move.l #$10001,d1
- jsr -198(a6)
- move.l d0,a0
- moveq #0,d0
- lea PP_FSHDSTART(a3),a1
-af1 move.b 0(a1,d0.w),14(a0,d0.w)
- addq.w #1,d0
- cmp.w #140,d0
- bne.s af1
- move.l a2,d0
- lsr.l #2,d0
- move.l d0,54(a0) ;seglist
- move.l a0,a1
- lea exter_name(pc),a0
- move.l a0,10(a1) ; name
- move.l PP_FSRES(a3),a0 ; FileSystem.resource
- lea 18(a0),a0 ; fsr_FileSysEntries
- jsr -$f0(a6) ;AddHead
- movem.l (sp)+,d0-d1/a0-a3/a6
- rts
-
-relocate: ;a0=pointer to executable, returns first segment in A0
- movem.l d1-d7/a1-a6,-(sp)
- move.l 4.w,a6
- move.l a0,a2
- cmp.l #$3f3,(a2)+
- bne.w ree
- addq.l #8,a2 ; skip name end and skip total hunks + 1
- move.l 4(a2),d7 ; last hunk
- sub.l (a2),d7 ; first hunk
- addq.l #8,a2 ; skip hunk to load first and hunk to load last
- addq.l #1,d7
- move.l a2,a3
- move.l d7,d0
- add.l d0,d0
- add.l d0,d0
- add.l d0,a3
- move.l a2,a4
-
- ; allocate hunks
- sub.l a5,a5 ;prev segment
- moveq #0,d6
-r15 move.l (a2),d2 ; hunk size (header)
- moveq #1,d1
- btst #30,d2 ; chip mem?
- beq.s r2
- bset #1,d1
-r2 bset #16,d1
- lsl.l #2,d2
- move.l d2,d0
- bne.s r17
- clr.l (a2)+ ; empty hunk
- bra.s r18
-r17 addq.l #8,d0 ; size + pointer to next hunk + hunk size
- jsr AllocMem(a6)
- tst.l d0
- beq.w ree
- move.l d0,a0
- move.l d2,(a0)+ ; store size
- move.l a0,(a2)+ ; store new pointer
- move.l a5,d1
- beq.s r10
- move.l a0,d0
- lsr.l #2,d0
- move.l d0,(a5)
-r10 move.l a0,a5
-r18 addq.l #1,d6
- cmp.l d6,d7
- bne.s r15
-
- moveq #0,d6
-r3 move.l d6,d1
- add.l d1,d1
- add.l d1,d1
- move.l 0(a4,d1.l),a0
- addq.l #4,a0
- move.l (a3)+,d3 ; hunk type
- move.l (a3)+,d4 ; hunk size
- lsl.l #2,d4
- cmp.l #$3e9,d3 ;code
- beq.s r4
- cmp.l #$3ea,d3 ;data
- bne.s r5
-r4
- ; code and data
- move.l d4,d0
-r6 tst.l d0
- beq.s r7
- move.b (a3)+,(a0)+
- subq.l #1,d0
- bra.s r6
-r5
- cmp.l #$3eb,d3 ;bss
- bne.s ree
-
-r7 ; scan for reloc32 or hunk_end
- move.l (a3)+,d3
- cmp.l #$3ec,d3 ;reloc32
- bne.s r13
-
- ; relocate
- move.l d6,d1
- add.l d1,d1
- add.l d1,d1
- move.l 0(a4,d1.l),a0 ; current hunk
- addq.l #4,a0
-r11 move.l (a3)+,d0 ;number of relocs
- beq.s r7
- move.l (a3)+,d1 ;hunk
- add.l d1,d1
- add.l d1,d1
- move.l 0(a4,d1.l),d3 ;hunk start address
- addq.l #4,d3
-r9 move.l (a3)+,d2 ;offset
- add.l d3,0(a0,d2.l)
- subq.l #1,d0
- bne.s r9
- bra.s r11
-r13
- cmp.l #$3f2,d3 ;end
- bne.s ree
-
- addq.l #1,d6
- cmp.l d6,d7
- bne.w r3
-
- moveq #1,d7
- move.l (a4),a0
-r0 move.l d7,d0
- movem.l (sp)+,d1-d7/a1-a6
- rts
-ree move.w #30000,d0
-re1 move.w #$f00,$dff180
- move.w #$00f,$dff180
- move.w #$0f0,$dff180
- dbf d0,re1
- moveq #0,d7
- bra.s r0
-
-fsres
- movem.l d1/a0-a2/a6,-(sp)
- move.l 4.w,a6
- lea $150(a6),a0 ;ResourceList
- move.l (a0),a0 ;lh_Head
-fsres3
- tst.l (a0) ;end of list?
- beq.s fsres1
- move.l 10(a0),a1 ;name
- lea fsresname(pc),a2
-fsres5
- move.b (a1)+,d0
- move.b (a2)+,d1
- cmp.b d1,d0
- bne.s fsres2
- tst.b d0
- beq.s fsres4
- bra.s fsres5
-fsres2
- move.l (a0),a0
- bra.s fsres3
- ; FileSystem.resource does not exist -> create it
-fsres1
- moveq #32,d0 ; sizeof(FileSysResource)
- move.l #$10001,d1
- jsr AllocMem(a6)
- move.l d0,a2
- move.b #8,8(a2) ; NT_RESOURCE
- lea fsresname(pc),a0
- move.l a0,10(a2) ; node name
- lea exter_name(pc),a0
- move.l a0,14(a2) ; fsr_Creator
- lea 18(a2),a0
- move.l a0,(a0) ; NewList() fsr_FileSysEntries
- addq.l #4,(a0)
- move.l a0,8(a0)
- lea $150(a6),a0 ; ResourceList
- move.l a2,a1
- jsr -$f6(a6) ; AddTail
- move.l a2,a0
-fsres4
- move.l a0,d0
- movem.l (sp)+,d1/a0-a2/a6
- rts
-
-addvolumenode
- move.l a6,-(sp)
- tst.b 32+44(a3)
- beq.s .end ;empty volume string = empty drive
- move.l 160(a3),a6
- cmp.w #37, 20(a6)
- bcs.s .prev37
- moveq #(1<<1)+(1<<3),d1 ;LDF_WRITE | LDF_VOLUMES
- jsr -$29A(a6) ;AttemptLockDosList
- and.l #~1,d0
- beq.s .end
- lea 32(a3),a0
- move.l a0,d1
- jsr -$2A6(a6) ;AddDosEntry
- moveq #(1<<1)+(1<<3),d1 ;LDF_WRITE | LDF_VOLUMES
- jsr -$294(a6) ;UnLockDosList
- bra.s .end
-.prev37 move.l 4.w,a6
- jsr -$0084(a6) ; Forbid
- move.l 160(a3),a0
- move.l 34(a0),a0 ; rootnode
- add.l a0,a0
- add.l a0,a0
- move.l 24(a0),a0 ; dosinfo
- add.l a0,a0
- add.l a0,a0
- lea 32(a3),a1
- move.l 4(a0),(a1)
- move.l a1,d0
- lsr.l #2,d0
- move.l d0,4(a0)
- jsr -$008a(a6) ;Permit
-.end move.l (sp)+,a6
- rts
-remvolumenode
- movem.l a2/a6,-(sp)
- move.l 160(a3),a6
- cmp.w #37, 20(a6)
- bcs.s .prev37
- moveq #(1<<1)+(1<<3),d1 ;LDF_WRITE | LDF_VOLUMES
- jsr -$29A(a6) ;AttemptLockDosList
- and.l #~1,d0
- beq.s .end
- lea 32(a3),a0
- move.l a0,d1
- jsr -$2A0(a6) ;RemDosEntry
- moveq #(1<<1)+(1<<3),d1 ;LDF_WRITE | LDF_VOLUMES
- jsr -$294(a6) ;UnLockDosList
- bra.s .end
-.prev37 move.l 4.w,a6
- jsr -$0084(a6) ; Forbid
- move.l 160(a3),a0
- move.l 34(a0),a0 ; rootnode
- add.l a0,a0
- add.l a0,a0
- move.l 24(a0),a0 ; dosinfo
- add.l a0,a0
- add.l a0,a0
- lea 4(a0),a1
- lea 32(a3),a2
-.pr2 move.l 4(a0),d0
- beq.s .pr1
- add.l d0,d0
- add.l d0,d0
- cmp.l d0,a2
- beq.s .pr3
- move.l d0,a1
- move.l (a1),a0
- add.l a0,a0
- add.l a0,a0
- bra.s .pr2
-.pr3 move.l (a2),(a1)
-.pr1 jsr -$008a(a6) ;Permit
-.end movem.l (sp)+,a2/a6
- rts
-
-diskinsertremove:
- movem.l d2/a2/a6,-(sp)
- moveq #22,d2
- sub.l d2,sp
- move.l sp,a2
- move.w d2,d1
-.l1 clr.b 0(a2,d1.w)
- subq.w #1,d1
- bne.s .l1
- move.l 4.w,a6
- moveq #15,d1 ;IECLASS_DISKREMOVED
- tst.l d0
- beq.s .l2
- moveq #16,d1 ;IECLASS_DISKINSERTED
-.l2 move.b d1,4(a2) ;ie_Class
- move.w #$0800,8(a2); ie_Qualifier=IEQUALIFIER_MULTIBROADCAST
-
- move.l 164(a3),a1
- move.w #11,28(a1) ;IND_WRITEEVENT
- move.l #22,36(a1) ;sizeof(struct InputEvent)
- move.l a2,40(a1)
- move.b #1,30(a1) ;IOF_QUICK
-
- move.l 168(a3),a1
- move.w #10,28(a1) ;TR_GETSYSTIME
- move.b #1,30(a1) ;IOF_QUICK
- jsr -$01c8(a6) ;DoIO
-
- move.l 168(a3),a1
- move.l 32(a1),14(a2)
- move.l 36(a1),18(a2)
-
- move.l 164(a3),a1
- jsr -$01c8(a6) ;DoIO
-
- add.l d2,sp
- movem.l (sp)+,d2/a2/a6
- rts
-
-dodiskchange
- tst.b d0
- beq.s .eject
- tst.b 32+44(a3)
- bne.s .end
- moveq #0,d0
-.dc2
- tst.b 32+45(a3,d0.w)
- beq.s .dc1
- addq.b #1,d0
- bra.s .dc2
-.dc1
- move.b d0,32+44(a3)
- beq.s .end
- bsr.w addvolumenode
- moveq #1,d0
- bsr.w diskinsertremove
- bra.s .end
-.eject
- tst.b 32+44(a3)
- beq.s .end
- clr.b 32+44(a3)
- bsr.w remvolumenode
- moveq #0,d0
- bsr.w diskinsertremove
-.end
- rts
-
-action_inhibit
- tst.l 20(a4) ;dp_Arg1
- beq.s .add
- moveq #0,d0
- bsr dodiskchange
- rts
-.add
- moveq #1,d0
- bsr dodiskchange
- rts
-
-diskchange
- tst.b 172(a3)
- bmi.s .nodisk
- moveq #1,d0
- bsr dodiskchange
- rts
-.nodisk
- moveq #0,d0
- bsr dodiskchange
- rts
-
- ; exall is complex, need to emulate eac_MatchString and/or eac_MatchFunc
-action_exall
- move.l 36(a4),a0 ; dp_Arg5, struct ExAllControl
- tst.l 8(a0) ; eac_MatchString
- bne.s .ex1
- tst.l 12(a0) ; eac_MatchFunc
- bne.s .ex1
- rts ;nothing to do here
-.ex1: movem.l d2-d7/a2-a6,-(sp)
- move.l a0,a5
- move.l 24(a4),a2 ;dp_Arg2, ExAllData
- move.l (a5),d7 ; eac_Entries
-.ex4 tst.l d7
- beq.s .ex3
- move.l a2,d0
- beq.s .ex3
- moveq #0,d6
- move.l 8(a5),d1 ; MatchString
- beq.s .ex5
- move.l 4(a2),d2 ; dir/file name
- move.l 160(a3),a6 ; dosbase
- jsr -$03cc(a6) ; MatchPatternNoCase
- tst.l d0
- bne.s .ex5
- st d6
-.ex5 move.l 12(a5),d1 ; MatchFunc
- beq.s .ex6
- move.l d1,a0
- move.l a2,a1
- move.l a2,-(sp)
- lea 32(a4),a2 ; dp_Arg4, Type
- pea .pop(pc)
- move.l 8(a0),-(sp)
- rts
-.pop move.l (sp)+,a2
- tst.l d0
- bne.s .ex6
- st d6
-.ex6 tst.b d6
- beq.s .ex7
- ; need to delete current entry.. this is not really the proper way..
- move.l 4(a2),d0 ; pointer to filename (which is first address after structure)
- sub.l a2,d0 ; copy this much data
- tst.l (a2) ; eac_Next
- beq.s .ex8
- move.l (a2),a0
- move.l a2,a1
-.ex9 move.l (a0)+,(a1)+
- subq.l #4,d1
- bpl.s .ex9
-.ex8 subq.l #1,(a5) ; eac_Entries
- subq.l #1,d7
- bra.s .ex4
-.ex7 move.l (a2),a2
- subq.l #1,d7
- bra.s .ex4
-.ex3 movem.l (sp)+,d2-d7/a2-a6
- rts
-
-
-
-make_dev: ; IN: A0 param_packet, D6: unit_no, D7: boot, A4: expansionbase
-
- bsr.w fsres
- move.l d0,PP_FSRES(a0) ; pointer to FileSystem.resource
- move.l a0,-(sp)
- move.w #$FFFC,d0 ; filesys base
- bsr.w getrtbase
- move.l (a0),a5
- move.w #$FF28,d0 ; fill in unit-dependent info (filesys_dev_storeinfo)
- bsr.w getrtbase
- move.l a0,a1
- move.l (sp)+,a0
- clr.l PP_FSSIZE(a0) ; filesystem size
- clr.l PP_FSPTR(a0) ; filesystem memory
- jsr (a1)
- ; ret:0=virtual,1=hardfile,2=rdbhardfile,-1=hardfile-donotmount,-2=no more subunits
- move.l d0,d3
- cmp.l #-2,d3
- beq.w general_ret
- cmp.l #2,d3
- beq.s mountalways
-
- ; KS < V36: init regular hardfiles only if filesystem is loaded
- and.l d5,d0
- beq.s mountalways ; >= 36
- tst.l PP_FSSIZE(a0)
- beq.w general_ret ; no filesystem -> don't mount
-
-mountalways
- ; allocate memory for loaded filesystem
- move.l PP_FSSIZE(a0),d0
- beq.s nordbfs1
- move.l a0,-(sp)
- moveq #1,d1
- move.l 4.w,a6
- jsr AllocMem(a6)
- move.l (sp)+,a0
- move.l d0,PP_FSPTR(a0)
-nordbfs1:
-
- tst.l d3
- bpl.s do_mount
-
- ; do not mount but we might need to load possible custom filesystem(s)
- move.l a0,a1
- move.w #$FF20,d0 ; record in ui.startup (filesys_dev_remember)
- bsr.w getrtbase
- jsr (a0)
- bra.w dont_mount
-
-do_mount:
- move.l a4,a6
- move.l a0,-(sp)
- jsr -144(a6) ; MakeDosNode()
- move.l (sp)+,a0 ; parmpacket
- move.l a0,a1
- move.l d0,a3 ; devicenode
- move.w #$FF20,d0 ; record in ui.startup (filesys_dev_remember)
- bsr.w getrtbase
- jsr (a0)
- moveq #0,d0
- move.l d0,8(a3) ; dn_Task
- move.l d0,16(a3) ; dn_Handler
- move.l d0,32(a3) ; dn_SegList
-
-dont_mount
- tst.l PP_FSPTR(a1) ; filesystem?
- beq.s nordbfs2
- move.l PP_FSPTR(a1),a0
- bsr.w relocate
- movem.l d0/a0-a1,-(sp)
- move.l PP_FSSIZE(a1),d0
- move.l PP_FSPTR(a1),a1
- move.l 4.w,a6
- jsr FreeMem(a6)
- movem.l (sp)+,d0/a0-a1
- tst.l d0
- beq.s nordbfs2
- bsr.w addfs
-nordbfs2:
-
- tst.l d3
- bmi.w general_ret
-
- move.w #$FF18,d0 ; update dn_SegList if needed (filesys_dev_bootfilesys)
- bsr.w getrtbase
- jsr (a0)
-
- move.l d3,d0
- move.b 79(a1),d3 ; bootpri
- tst.l d0
- bne.b MKDV_doboot
-
-MKDV_is_filesys:
- move.l #4000,20(a3) ; dn_StackSize
- lea.l our_seglist(pc),a1
- move.l a1,d0
- lsr.l #2,d0
- move.l d0,32(a3) ; dn_SegList
- moveq #-1,d0
- move.l d0,36(a3) ; dn_GlobalVec
-
-MKDV_doboot:
- tst.l d7
- beq.b MKDV_noboot
-
- move.l 4.w,a6
- moveq.l #20,d0
- moveq.l #0,d1
- jsr AllocMem(a6)
- move.l d0,a1 ; bootnode
- moveq #0,d0
- move.l d0,(a1)
- move.l d0,4(a1)
- move.w d0,14(a1)
- move.w #$1000,d0
- or.b d3,d0
- move.w d0,8(a1)
- move.l $104(a5),10(a1) ; filesys_configdev
- move.l a3,16(a1) ; devicenode
- lea.l 74(a4),a0 ; MountList
- jmp -270(a6) ; Enqueue()
-
-MKDV_noboot:
- move.l a3,a0
- moveq #0,d1
- move.l d1,a1
- moveq #-1,d0
- move.l a4,a6 ; expansion base
- jmp -150(a6) ; AddDosNode
-
-filesys_mainloop:
- move.l 4.w,a6
- sub.l a1,a1
- jsr -294(a6) ; FindTask
- move.l d0,a0
- lea.l $5c(a0),a5 ; pr_MsgPort
-
- ; Open DOS library
- lea.l doslibname(pc),a1
- moveq.l #0,d0
- jsr -552(a6) ; OpenLibrary
- move.l d0,a2
-
- ; Allocate some memory. Usage:
- ; 0: lock chain
- ; 4: command chain
- ; 8: second thread's lock chain
- ; 12: dummy message
- ; 32: the volume (80+44+1 bytes)
- ; 157: mousehack started-flag
- ; 160: dosbase
- ; 164: input.device ioreq (disk inserted/removed input message)
- ; 168: timer.device ioreq
- ; 172: disk change from host
- ; 176: my task
- move.l #12+20+(80+44+1)+(1+3)+4+4+4+(1+3)+4,d0
- move.l #$10001,d1 ; MEMF_PUBLIC | MEMF_CLEAR
- jsr AllocMem(a6)
- move.l d0,a3
- moveq.l #0,d6
- move.l d6,(a3)
- move.l d6,4(a3)
- move.l d6,8(a3)
- move.l a2,160(a3)
-
- sub.l a1,a1
- jsr -294(a6) ; FindTask
- move.l d0,176(a3)
-
- bsr.w allocinputdevice
- move.l d0,164(a3)
- bsr.w alloctimerdevice
- move.l d0,168(a3)
-
- moveq.l #0,d5 ; No commands queued.
-
- ; Fetch our startup packet
- move.l a5,a0
- jsr -384(a6) ; WaitPort
- move.l a5,a0
- jsr -372(a6) ; GetMsg
- move.l d0,a4
- move.l 10(a4),d3 ; ln_Name
- move.w #$FF40,d0 ; startup_handler
- bsr.w getrtbase
- moveq.l #0,d0
- jsr (a0)
-
- bsr.w addvolumenode
-
- bsr.w mousehack_init
- bra.w FSML_Reply
-
- ; We abuse some of the fields of the message we get. Offset 0 is
- ; used for chaining unprocessed commands, and offset 1 is used for
- ; indicating the status of a command. 0 means the command was handed
- ; off to some UAE thread and did not complete yet, 1 means we didn't
- ; even hand it over yet because we were afraid that might blow some
- ; pipe limit, and -1 means the command was handed over and has completed
- ; processing by now, so it's safe to reply to it.
-
-FSML_loop:
- bsr.w mousehack_init
-
- move.l a5,a0
- jsr -372(a6) ; GetMsg
- move.l d0,a4
- tst.l d0
- bne.s .msg
-
- moveq #0,d0
- move.b 15(a5),d1 ;mp_SigBit
- bset d1,d0
- bset #17,d0 ; SIGBREAK_CTRL_D
- jsr -$013e(a6) ;Wait
-.msg
- ; disk changed?
- tst.b 172(a3)
- beq.s .nodc
- bsr.w diskchange
- clr.b 172(a3)
-.nodc
- move.l a4,d0
- beq.s FSML_loop
-
- ; notify reply?
- cmp.w #38, 18(a4)
- bne.s nonotif
- cmp.l #NOTIFY_CLASS, 20(a4)
- bne.s nonotif
- cmp.w #NOTIFY_CODE, 24(a4)
- bne.s nonotif
- move.l 26(a4),a0 ; NotifyRequest
- move.l 12(a0),d0 ; flags
- and.l #NRF_WAIT_REPLY|NRF_MAGIC,d0
- cmp.l #NRF_WAIT_REPLY|NRF_MAGIC,d0
- bne.s nonoti
- and.l #~NRF_MAGIC,12(a0)
- move.l 16(a0),a0
- move.l a4,a1
- move.b #8,(a1)
- jsr -366(a6) ; PutMsg
- bra.s FSML_loop
-nonoti
- move.l a4,a1
- moveq #38,d0
- jsr FreeMem(a6)
- bra.w FSML_loop
-
-nonotif
- move.l 10(a4),d3 ; ln_Name
- bne.b FSML_FromDOS
-
- ; It's a dummy packet indicating that some queued command finished.
- move.w #$FF50,d0 ; exter_int_helper
- bsr.w getrtbase
- moveq.l #1,d0
- jsr (a0)
- ; Go through the queue and reply all those that finished.
- lea.l 4(a3),a2
- move.l (a2),a0
-FSML_check_old:
- move.l a0,d0
- beq.w FSML_loop
- move.l (a0),a1
- move.l d0,a0
- ; This field may be accessed concurrently by several UAE threads.
- ; This _should_ be harmless on all reasonable machines.
- move.l 4(a0),d0
- bpl.b FSML_check_next
- movem.l a0/a1,-(a7)
- move.l 10(a0),a4
- bsr.b ReplyOne
- subq.l #1,d5 ; One command less in the queue
- movem.l (a7)+,a0/a1
- move.l a1,(a2)
- move.l a1,a0
- bra.b FSML_check_old
-FSML_check_next:
- move.l a0,a2
- move.l a1,a0
- bra.b FSML_check_old
-
-FSML_FromDOS:
- ; Limit the number of outstanding started commands. We can handle an
- ; unlimited number of unstarted commands.
- cmp.l #20,d5
- bcs FSML_DoCommand
- ; Too many commands queued.
- moveq.l #1,d0
- move.l d0,4(a4)
- bra.b FSML_Enqueue
-
-FSML_DoCommand:
- bsr.b LockCheck ; Make sure there are enough locks for the C code to grab.
- move.w #$FF30,d0 ; filesys_handler
- bsr.w getrtbase
- jsr (a0)
- tst.l d0
- beq.b FSML_Reply
- ; The command did not complete yet. Enqueue it and increase number of
- ; queued commands
- ; The C code already set 4(a4) to 0
- addq.l #1,d5
-FSML_Enqueue:
- move.l 4(a3),(a4)
- move.l a4,4(a3)
- bra.w FSML_loop
-
-FSML_Reply:
- move.l d3,a4
- bsr.b ReplyOne
- bra.w FSML_loop
-
-ReplyOne:
- cmp.l #31,8(a4) ;ACTION_INHIBIT?
- bne.s FSML_ReplyOne2
- bsr.w action_inhibit
-FSML_ReplyOne2:
- cmp.l #1033,8(a4) ;ACTION_EXAMINE_ALL
- bne.s FSML_ReplyOne3
- bsr.w action_exall
-FSML_ReplyOne3:
- move.l (a4),a1 ; dp_Link
- move.l 4(a4),a0 ; dp_Port
- move.l a5,4(a4)
- jmp -366(a6) ; PutMsg
-
-; ugly code to avoid calling AllocMem / FreeMem from native C code.
-; We keep a linked list of 3 locks. In theory, only one should ever
-; be used. Before handling every packet, we check that the list has the
-; right length.
-
-LockCheck:
- move.l d5,-(a7)
- moveq.l #-4,d5 ; Keep three locks
- move.l (a3),a2
- move.l a2,d7
-LKCK_Loop:
- move.l a2,d1
- beq LKCK_ListEnd
- addq.l #1,d5
- beq.b LKCK_TooMany
- move.l a2,a1
- move.l (a2),a2
- bra.b LKCK_Loop
-LKCK_ListEnd:
- addq.l #1,d5
- beq.b LKCK_ret
- move.l d7,a2
- moveq.l #24,d0 ; sizeof Lock is 20, 4 for chain
- moveq.l #1,d1 ; MEMF_PUBLIC
- jsr AllocMem(a6)
- addq.w #1,d6
- move.l d0,a2
- move.l d7,(a2)
- move.l a2,d7
- bra.b LKCK_ListEnd
-LKCK_TooMany:
- move.l (a2),d0 ; We have too many, but we tolerate that to some extent.
- beq.b LKCK_ret
- move.l d0,a0
- move.l (a0),d0
- beq.b LKCK_ret
- move.l d0,a0
- move.l (a0),d0
- beq.b LKCK_ret
-
- moveq.l #0,d0 ; Now we are sure that we really have too many. Delete some.
- move.l d0,(a1)
-LKCK_TooManyLoop:
- move.l a2,a1
- move.l (a1),a2
- moveq.l #24,d0
- jsr FreeMem(a6)
- add.l #$10000,d6
- move.l a2,d0
- bne.b LKCK_TooManyLoop
-LKCK_ret:
- move.l d7,(a3)
- move.l (a7)+,d5
- rts
-
-getrtbase:
- lea start-8-4(pc),a0
- and.l #$FFFF,d0
- add.l d0,a0
- rts
-
- ;p96 stuff
-
-p96flag dc.w 0
-p96vsyncfix1
- cmp.l #34,8(sp) ; picasso_WaitVerticalSync?
- bne.s p961
- movem.l d0-d1/a0-a2/a6,-(sp)
- move.l 4.w,a6
- sub.l a1,a1
- jsr -$126(a6) ; FindTask
- move.l d0,a2
- move.l a2,a1
- moveq #-20,d0
- jsr -$12c(a6) ; SetTaskPri
- lea p96flag(pc),a0
- move.w (a0),d1
-p962 cmp.w (a0),d1
- beq.s p962
- move.l a2,a1
- jsr -$12c(a6) ; SetTaskPri
- moveq #1,d1
- movem.l (sp)+,d0-d1/a0-a2/a6
- addq.l #4,sp ; return directly to caller
-p961 rts
-
-
-; mouse hack
-
-newlist:
- move.l a0,(a0)
- addq.l #4,(a0)
- clr.l 4(a0)
- move.l a0,8(a0)
- rts
-
-createport:
- movem.l d2/a2/a6,-(sp)
- move.l 4,a6
- moveq #-1,d0
- jsr -$014a(a6) ;AllocSignal
- sub.l a0,a0
- move.l d0,d2
- bmi.s .f
- moveq #34,d0
- move.l #65536+1,d1
- jsr AllocMem(a6)
- sub.l a0,a0
- move.l d0,a2
- tst.l d0
- beq.s .f
- move.b #4,8(a2) ;NT_MSGPORT
- move.b d2,15(a2)
- sub.l a1,a1
- jsr -$0126(a6) ;FindTask
- move.l d0,16(a2)
- lea 20(a2),a0
- bsr.w newlist
- move.l a2,a0
-.f move.l a0,d0
- movem.l (sp)+,d2/a2/a6
- rts
-
-createio:
- movem.l d2/a2/a6,-(sp)
- move.l 4,a6
- tst.l d0
- beq.s .f
- move.l d0,a2
- moveq #48,d2
- move.l d2,d0
- move.l #65536+1,d1
- jsr AllocMem(a6)
- move.l d0,a0
- move.b #10,8(a0) ;NT_MESSAGE
- move.l d2,18(a0)
- move.l a2,14(a0)
-.f tst.l d0
- movem.l (sp)+,d2/a2/a6
- rts
-
-allocinputdevice
- movem.l a2/a6,-(sp)
- move.l 4.w,a6
- bsr.w createport
- bsr.w createio
- beq.s .f
- move.l d0,a1
- move.l d0,a2
- lea inp_dev(pc),a0
- moveq #0,d0
- moveq #0,d1
- jsr -$01bc(a6) ;OpenDevice
- move.l d0,d1
- moveq #0,d0
- tst.l d1
- bne.s .f
- move.l a2,d0
-.f tst.l d0
- movem.l (sp)+,a2/a6
- rts
-
-alloctimerdevice
- movem.l a2/a6,-(sp)
- move.l 4.w,a6
- bsr.w createport
- bsr.w createio
- beq.s .f
- move.l d0,a2
- move.l d0,a1
- lea tim_dev(pc),a0
- moveq #0,d0
- moveq #0,d1
- jsr -$01bc(a6) ;OpenDevice
- move.l d0,d1
- moveq #0,d0
- tst.l d1
- bne.s .f
- move.l a2,d0
-.f tst.l d0
- movem.l (sp)+,a2/a6
- rts
-
-createtask:
- movem.l d2/d3/a2/a3/a6,-(sp)
- move.l 4,a6
- move.l a0,d2
- move.l a1,d3
- move.l #92+2048,d0
- move.l #65536+1,d1
- jsr AllocMem(a6)
- tst.l d0
- beq .f
- move.l d0,a2
- move.b #1,8(a2) ;NT_TASK
- move.l d2,10(a2)
- lea 92(a2),a3
- move.l a3,58(a2)
- lea 2048(a3),a3
- move.l a3,62(a2)
- move.l a3,54(a2)
- move.l a2,a1
- move.l d3,a2
- sub.l a3,a3
- jsr -$011a(a6) ;AddTask
-.f movem.l (sp)+,d2/d3/a2/a3/a6
- rts
-
-mousehack_e: dc.w 0
-mousehack_x: dc.w 0
-mousehack_y: dc.w 0
-
-MH_INT = 0
-MH_FOO = (MH_INT+22)
-MH_IEV = (MH_FOO+16)
-MH_IO = (MH_IEV+22)
-MH_TM = (MH_IO+4)
-MH_END = (MH_TM+4)
-
-mousehack_init:
- move.l a0,-(sp)
- tst.b 157(a3)
- bne.s .no
- lea mousehack_e(pc),a0
- cmp.b #1,(a0)
- bne.s .no
- lea mhname(pc),a0
- lea mousehack_task(pc),a1
- bsr createtask
- st 157(a3)
- ;tell native side that mousehack is active
- move.w #$FF38,d0
- bsr.w getrtbase
- jsr (a0)
-.no move.l (sp)+,a0
- rts
-
-mousehack_task:
- move.l 4,a6
-
- moveq #-1,d0
- jsr -$014a(a6) ;AllocSignal
- moveq #0,d2
- bset d0,d2
-
- sub.l a1,a1
- jsr -$0126(a6) ;FindTask
- move.l d0,a4
-
- moveq #20,d0
- move.l a4,a1
- jsr -$012c(a6) ;SetTaskPri
-
- moveq #0,d0
- lea intlibname(pc),a1
- jsr -$0228(a6)
- move.l d0,d7
-
- moveq #0,d0
- move.w #MH_END,d0
- move.l #65536+1,d1
- jsr AllocMem(a6)
- move.l d0,a5
-
- bsr.w allocinputdevice
- move.l d0,MH_IO(a5)
- beq.w .f
- bsr.w alloctimerdevice
- move.l d0,MH_TM(a5)
- beq.w .f
-
- lea MH_FOO(a5),a3
- move.l a4,12(a3);task
- move.l d2,8(a3) ;sigmask
- moveq #-1,d0
- move.l d0,(a3) ;mx
- move.l d0,4(a3) ;my
-
- lea MH_INT(a5),a1
- move.b #2,8(a1) ;NT_INTERRUPT
- move.b #5,9(a1) ;priority
- lea mhname(pc),a0
- move.l a0,10(a1)
- lea mousehackint(pc),a0
- move.l a0,18(a1)
- move.l a3,14(a1)
- moveq #5,d0 ;INTB_VERTB
- jsr -$00a8(a6)
- bra.s mhloop
-.f rts
-
-mhloop
- move.l d2,d0
- jsr -$013e(a6) ;Wait
-
- 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 #1,30(a1) ;IOF_QUICK
-
- move.b #4,4(a2) ;IECLASS_POINTERPOS
- clr.b 5(a2) ;ie_SubClass
- clr.w 6(a2) ;ie_Code
- clr.w 8(a2) ;ie_Qualifier
-
- move.l d7,a0 ;intbase
-
- move.l MH_FOO+0(a5),d0
- move.w 34+14(a0),d1
- add.w d1,d1
- sub.w d1,d0
- move.w d0,10(a2)
-
- move.l MH_FOO+4(a5),d0
- move.w 34+12(a0),d1
- add.w d1,d1
- sub.w d1,d0
- ext.l d0
- move.w d0,12(a2)
-
- 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
- jsr -$01c8(a6) ;DoIO
-
- bra.w mhloop
-
-mousehackint:
- move.w mousehack_x(pc),d0
- ext.l d0
- move.w mousehack_y(pc),d1
- ext.l d1
- cmp.l (a1),d0
- bne .l1
- cmp.l 4(a1),d1
- beq .l2
-.l1 move.l d1,4(a1)
- move.l d0,(a1)
- move.l 8(a1),d0
- move.l 12(a1),a1
- move.l 4.w,a6
- jsr -$0144(a6) ; Signal
-.l2 lea $dff000,a0
- moveq #0,d0
- rts
-
-inp_dev: dc.b 'input.device',0
-tim_dev: dc.b 'timer.device',0
-mhname: dc.b 'UAE mouse hack',0
-exter_name: dc.b 'UAE filesystem',0
-doslibname: dc.b 'dos.library',0
-intlibname: dc.b 'intuition.library',0
-explibname: dc.b 'expansion.library',0
-fsresname: dc.b 'FileSystem.resource',0
- END
//write_log ( "keyboard = %d scancode = 0x%02x state = %d\n", keyboard, scancode, newstate );
if (newstate) {
- switch (scancode)
- {
- case DIK_F12:
+
+ if (scancode == DIK_F12 || scancode == currprefs.win32_guikey) {
if (ctrlpressed ()) {
code = AKS_TOGGLEFULLSCREEN;
} else if (shiftpressed () || specialpressed ()) {
} else {
code = AKS_ENTERGUI;
}
- break;
+ }
+
+ switch (scancode)
+ {
+ case DIK_F12:
case DIK_F11:
if (currprefs.win32_ctrl_F11_is_quit) {
if (ctrlpressed ())
#include "serial.h"
#include "savestate.h"
#include "ahidsound_new.h"
+#include "uaeipc.h"
#include <Ghostscript/errors.h>
#include <Ghostscript/iapi.h>
cnt++;
}
}
+ if (isIPC (COMPIPENAME)) {
+ comports[j].dev = xmalloc(100);
+ sprintf (comports[cnt].dev, "\\\\.\\pipe\\%s", COMPIPENAME);
+ comports[j].cfgname = my_strdup (COMPIPENAME);
+ comports[j].name = my_strdup (COMPIPENAME);
+ }
write_log ("Serial port enumeration end\n");
return cnt;
}
if (ovrun)
serdatr |= 0x8000;
#if SERIALDEBUG > 2
- write_log ( "SERIAL: read 0x%04x (%c) %x\n", serdatr, dochar (serdatr), m68k_getpc ());
+ write_log ( "SERIAL: read 0x%04x (%c) %x\n", serdatr, dochar (serdatr), M68K_GETPC);
#endif
ovrun = 0;
data_in_serdatr = 0;
static SYSTEM_INFO SystemInfo;
static int logging_started;
static DWORD minidumpmode = MiniDumpNormal;
+void *globalipc, *serialipc;
int qpcdivisor = 0;
int cpu_mmx = 1;
rp_vsync ();
#endif
cnt = 0;
- while (checkIPC (&currprefs));
+ while (checkIPC (globalipc, &currprefs));
if (quit_program)
break;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
- while (checkIPC (&currprefs));
+ while (checkIPC (globalipc, &currprefs));
if (was_paused) {
resumepaused ();
sound_closed = 0;
p->win32_notaskbarbutton = 0;
p->win32_alwaysontop = 0;
p->win32_specialkey = 0xcf; // DIK_END
+ p->win32_guikey = -1;
p->win32_automount_removable = 0;
p->win32_automount_drives = 0;
p->win32_automount_cddrives = 0;
cfgfile_target_dwrite (f, "always_on_top=%s\n", p->win32_alwaysontop ? "true" : "false");
cfgfile_target_dwrite (f, "no_recyclebin=%s\n", p->win32_norecyclebin ? "true" : "false");
cfgfile_target_dwrite (f, "specialkey=0x%x\n", p->win32_specialkey);
+ if (p->win32_guikey >= 0)
+ cfgfile_target_dwrite (f, "guikey=0x%x\n", p->win32_guikey);
cfgfile_target_dwrite (f, "kbledmode=%d\n", p->win32_kbledmode);
cfgfile_target_dwrite (f, "powersavedisabled=%s\n", p->win32_powersavedisabled ? "true" : "false");
|| cfgfile_yesno (option, value, "powersavedisabled", &p->win32_powersavedisabled)
|| cfgfile_yesno (option, value, "magic_mouse", &p->win32_outsidemouse)
|| cfgfile_intval (option, value, "specialkey", &p->win32_specialkey, 1)
+ || cfgfile_intval (option, value, "guikey", &p->win32_guikey, 1)
|| cfgfile_intval (option, value, "kbledmode", &p->win32_kbledmode, 1)
|| cfgfile_intval (option, value, "cpu_idle", &p->cpu_idle, 1));
#ifdef PARALLEL_PORT
paraport_mask = paraport_init ();
#endif
- createIPC ();
+ globalipc = createIPC ("WinUAE", 0);
+ serialipc = createIPC (COMPIPENAME, 1);
enumserialports ();
real_main (argc, argv);
}
}
- closeIPC ();
+ closeIPC (globalipc);
+ closeIPC (serialipc);
write_disk_history ();
timeend ();
#ifdef AVIOUTPUT
#define WINUAEPUBLICBETA 1
-#define WINUAEBETA "2"
-#define WINUAEDATE MAKEBD(2008, 11, 22)
+#define WINUAEBETA "3"
+#define WINUAEDATE MAKEBD(2008, 11, 29)
#define WINUAEEXTRA ""
#define WINUAEREV ""
extern int manual_palette_refresh_needed;
extern int mouseactive, focus;
extern int ignore_messages_all;
+extern void *globalipc, *serialipc;
extern char start_path_exe[MAX_DPATH];
extern char start_path_data[MAX_DPATH];
static uae_u8 *ddraw_dolock (void)
{
+ if (dx_islost ())
+ return 0;
if (!DirectDraw_SurfaceLock ())
return 0;
gfxvidinfo.bufmem = DirectDraw_GetSurfacePointer ();
if (idx >= 0)
idx += 2;
else
- idx = 0;
+ idx = 1;
if (idx >= total)
idx = 0;
SendDlgItemMessage (hDlg, id, CB_SETCURSEL, idx, 0);
for (;;) {
HANDLE IPChandle;
- IPChandle = geteventhandleIPC ();
+ IPChandle = geteventhandleIPC (globalipc);
if (IPChandle != INVALID_HANDLE_VALUE) {
MsgWaitForMultipleObjects (1, &IPChandle, FALSE, INFINITE, QS_ALLINPUT);
- while (checkIPC (&workprefs));
+ while (checkIPC (globalipc, &workprefs));
} else {
WaitMessage();
}
+Beta 3:
+
+- HAM errors if left border was not fully visible (it seems this bug
+ has been there since the beginning of UAE, code that was supposed
+ to handle this case has never worked correctly..)
+- mid horizontal line HAM/EHB/DPF change fixed (Cover Girl Strip
+ Poker) broke in 1.5.3
+- added win32.guikey to configuration file, keycode that opens GUI
+ (raw directinput keycode, for example F10 = 0x44) -1 = default.
+- game & io-ports <none>-setting works properly
+- vhd creator didn't create fully compatible images (larger images
+ were incompatible with official vhd tools, did not cause data
+ corruption)
+- 1st Anniversary by Lazy Bones OCS/ECS "7-plane" trick emulated
+ (missing black vertical lines)
+- Disposable Hero title screen is now perfect. Take screenshots
+ before it gets broken again :)
+- added some more sanity tests to DirectDraw surface handling
+
Beta 2:
- fixed b1 slowdown when lots of sprites are visible
modes if pad was not "connected"
- another partial sprite rendering update, fixes sprite size problems
in screen modes that have multiple resolutions in single horizontal
- line (for example Innovation Part 2 by Axis is 100% correct now)
+ line (for example Innovation Part 2 by Axxis is 100% correct now)
- also fixes wrong sized sprites in some lores resolution modes
- superhires in lores mode supported (show only every 4th pixel)
- superhires in filtered lores supported (visible pixel is average
- configuration cache loader missed most configuration files inside
directories (parent was set to wrong entry..)
- some midline resolution change updates. Disposable Hero looks better
- but not perfect yet.. Innovation Part 2 by Axis also looks better
+ but not perfect yet.. Innovation Part 2 by Axxis also looks better
(sprite resolution issue still remaining). Brian the Lion "message
dialog" corruption fixed.
}
}
- } else
+ } else {
write_log ("Illegal emulator trap %d\n", trap_num);
+ }
}
#include <windows.h>
-static HANDLE hipc = INVALID_HANDLE_VALUE, olevent = INVALID_HANDLE_VALUE;
-static OVERLAPPED ol;
#define IPC_BUFFER_SIZE 16384
-static uae_u8 buffer[IPC_BUFFER_SIZE], outbuf[IPC_BUFFER_SIZE];
-static int connected, readpending, writepending;
+#define MAX_OUTMESSAGES 30
+#define MAX_BINMESSAGE 32
+
+struct uaeipc
+{
+ HANDLE hipc, olevent;
+ OVERLAPPED ol;
+ uae_u8 buffer[IPC_BUFFER_SIZE], outbuf[IPC_BUFFER_SIZE];
+ int connected, readpending, writepending;
+ int binary;
+ char *outmsg[MAX_OUTMESSAGES];
+ int outmessages;
+ uae_u8 outbin[MAX_OUTMESSAGES][MAX_BINMESSAGE];
+ int outbinlen[MAX_OUTMESSAGES];
+};
static void parsemessage(char *in, struct uae_prefs *p, char *out, int outsize)
{
}
}
-static int listenIPC(void)
+static int listenIPC(struct uaeipc *ipc)
{
DWORD err;
- memset(&ol, 0, sizeof ol);
- ol.hEvent = olevent;
- if (ConnectNamedPipe(hipc, &ol)) {
+ memset(&ipc->ol, 0, sizeof (OVERLAPPED));
+ ipc->ol.hEvent = ipc->olevent;
+ if (ConnectNamedPipe(ipc->hipc, &ipc->ol)) {
write_log ("IPC: ConnectNamedPipe init failed, err=%d\n", GetLastError());
- closeIPC();
+ closeIPC(ipc);
return 0;
}
err = GetLastError();
if (err == ERROR_PIPE_CONNECTED) {
- if (SetEvent(olevent)) {
+ if (SetEvent(ipc->olevent)) {
write_log ("IPC: ConnectNamedPipe SetEvent failed, err=%d\n", GetLastError());
- closeIPC();
+ closeIPC(ipc);
return 0;
}
} else if (err != ERROR_IO_PENDING) {
write_log ("IPC: ConnectNamedPipe failed, err=%d\n", err);
- closeIPC();
+ closeIPC(ipc);
return 0;
}
- write_log ("IPC: waiting for connections\n");
return 1;
}
-static void disconnectIPC(void)
+static void disconnectIPC(struct uaeipc *ipc)
{
- readpending = writepending = FALSE;
- if (connected) {
- if (!DisconnectNamedPipe(hipc))
+ ipc->readpending = ipc->writepending = FALSE;
+ if (ipc->connected) {
+ if (!DisconnectNamedPipe(ipc->hipc))
write_log ("IPC: DisconnectNamedPipe failed, err=%d\n", GetLastError());
- connected = FALSE;
+ ipc->connected = FALSE;
}
}
-static void resetIPC(void)
+static void resetIPC(struct uaeipc *ipc)
{
- disconnectIPC();
- listenIPC();
+ disconnectIPC(ipc);
+ listenIPC(ipc);
}
-void closeIPC(void)
+void closeIPC(struct uaeipc *ipc)
{
- disconnectIPC();
- if (hipc == INVALID_HANDLE_VALUE)
+ disconnectIPC(ipc);
+ if (ipc->hipc == INVALID_HANDLE_VALUE)
return;
- CloseHandle(hipc);
- hipc = INVALID_HANDLE_VALUE;
- if (olevent != INVALID_HANDLE_VALUE)
- CloseHandle (olevent);
- olevent = INVALID_HANDLE_VALUE;
-
+ CloseHandle(ipc->hipc);
+ ipc->hipc = INVALID_HANDLE_VALUE;
+ if (ipc->olevent != INVALID_HANDLE_VALUE)
+ CloseHandle (ipc->olevent);
+ ipc->olevent = INVALID_HANDLE_VALUE;
+ xfree (ipc);
}
-int createIPC(void)
+void *createIPC(const char *name, int binary)
{
char tmpname[100];
int cnt = 0;
+ struct uaeipc *ipc;
- connected = FALSE;
- readpending = FALSE;
- writepending = FALSE;
- olevent = INVALID_HANDLE_VALUE;
+ ipc = xcalloc (sizeof (struct uaeipc), 1);
+ ipc->connected = FALSE;
+ ipc->readpending = FALSE;
+ ipc->writepending = FALSE;
+ ipc->olevent = INVALID_HANDLE_VALUE;
+ ipc->binary = 1;
while (cnt < 10) {
- strcpy (tmpname, "\\\\.\\pipe\\WinUAE");
+ sprintf (tmpname, "\\\\.\\pipe\\%s", name);
if (cnt > 0) {
char *p = tmpname + strlen (tmpname);
sprintf(p, "_%d", cnt);
}
- hipc = CreateNamedPipe(tmpname,
+ ipc->hipc = CreateNamedPipe(tmpname,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
1, IPC_BUFFER_SIZE, IPC_BUFFER_SIZE,
NMPWAIT_USE_DEFAULT_WAIT, NULL);
- if (hipc == INVALID_HANDLE_VALUE) {
+ if (ipc->hipc == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
if (err == ERROR_ALREADY_EXISTS || err == ERROR_PIPE_BUSY) {
cnt++;
break;
}
write_log ("IPC: Named Pipe '%s' open\n", tmpname);
- olevent = CreateEvent(NULL, TRUE, TRUE, NULL);
- return listenIPC();
+ ipc->olevent = CreateEvent(NULL, TRUE, TRUE, NULL);
+ if (listenIPC(ipc))
+ return ipc;
+ closeIPC(ipc);
+ return NULL;
}
-void *geteventhandleIPC(void)
+void *geteventhandleIPC(struct uaeipc *ipc)
{
- return olevent;
+ return ipc->olevent;
}
-#define MAX_OUTMESSAGES 30
-static char *outmsg[MAX_OUTMESSAGES];
-static int outmessages;
-
-int sendIPC(char *msg)
+int sendIPC(struct uaeipc *ipc, char *msg)
{
- if (hipc == INVALID_HANDLE_VALUE)
+ if (ipc->hipc == INVALID_HANDLE_VALUE)
return 0;
- if (outmessages >= MAX_OUTMESSAGES)
+ if (ipc->outmessages >= MAX_OUTMESSAGES)
return 0;
- outmsg[outmessages++] = my_strdup (msg);
- if (!readpending && !writepending)
- SetEvent (olevent);
+ ipc->outmsg[ipc->outmessages++] = my_strdup (msg);
+ if (!ipc->readpending && !ipc->writepending)
+ SetEvent (ipc->olevent);
+ return 1;
+}
+int sendBinIPC(struct uaeipc *ipc, uae_u8 *msg, int len)
+{
+ if (ipc->hipc == INVALID_HANDLE_VALUE)
+ return 0;
+ if (ipc->outmessages >= MAX_OUTMESSAGES)
+ return 0;
+ ipc->outbinlen[ipc->outmessages] = len;
+ memcpy (&ipc->outbin[ipc->outmessages++][0], msg, len);
+ if (!ipc->readpending && !ipc->writepending)
+ SetEvent (ipc->olevent);
return 1;
}
-int checkIPC(struct uae_prefs *p)
+int checkIPC(struct uaeipc *ipc, struct uae_prefs *p)
{
BOOL ok;
DWORD ret, err;
- if (hipc == INVALID_HANDLE_VALUE)
+ if (ipc->hipc == INVALID_HANDLE_VALUE)
return 0;
- if (WaitForSingleObject(olevent, 0) != WAIT_OBJECT_0)
+ if (WaitForSingleObject(ipc->olevent, 0) != WAIT_OBJECT_0)
return 0;
- if (!readpending && !writepending && outmessages > 0) {
- memset (&ol, 0, sizeof ol);
- ol.hEvent = olevent;
- ok = WriteFile(hipc, outmsg[outmessages], strlen (outmsg[outmessages]) + 1, &ret, &ol);
- xfree(outmsg[outmessages--]);
+ if (!ipc->readpending && !ipc->writepending && ipc->outmessages > 0) {
+ memset (&ipc->ol, 0, sizeof (OVERLAPPED));
+ ipc->ol.hEvent = ipc->olevent;
+ if (ipc->binary) {
+ ok = WriteFile(ipc->hipc, &ipc->outbin[ipc->outmessages][0], ipc->outbinlen[ipc->outmessages], &ret, &ipc->ol);
+ } else {
+ ok = WriteFile(ipc->hipc, ipc->outmsg[ipc->outmessages], strlen (ipc->outmsg[ipc->outmessages]) + 1, &ret, &ipc->ol);
+ }
+ xfree(ipc->outmsg[ipc->outmessages--]);
err = GetLastError();
if (!ok && err != ERROR_IO_PENDING) {
write_log ("IPC: WriteFile() err=%d\n", err);
- resetIPC();
+ resetIPC(ipc);
return 0;
}
- writepending = TRUE;
+ ipc->writepending = TRUE;
return 1;
}
- if (readpending || writepending) {
- ok = GetOverlappedResult(hipc, &ol, &ret, FALSE);
+ if (ipc->readpending || ipc->writepending) {
+ ok = GetOverlappedResult(ipc->hipc, &ipc->ol, &ret, FALSE);
if (!ok) {
err = GetLastError();
if (err == ERROR_IO_INCOMPLETE)
return 0;
write_log ("IPC: GetOverlappedResult error %d\n", err);
- resetIPC();
+ resetIPC(ipc);
return 0;
}
- if (!connected) {
+ if (!ipc->connected) {
write_log ("IPC: Pipe connected\n");
- connected = TRUE;
+ ipc->connected = TRUE;
return 0;
}
- if (writepending) {
- writepending = FALSE;
- SetEvent (ol.hEvent);
- memset (&ol, 0, sizeof ol);
- ol.hEvent = olevent;
+ if (ipc->writepending) {
+ ipc->writepending = FALSE;
+ SetEvent (ipc->ol.hEvent);
+ memset (&ipc->ol, 0, sizeof (OVERLAPPED));
+ ipc->ol.hEvent = ipc->olevent;
return 0;
}
}
- if (!readpending) {
- ok = ReadFile(hipc, buffer, IPC_BUFFER_SIZE, &ret, &ol);
+ if (!ipc->readpending) {
+ ok = ReadFile(ipc->hipc, ipc->buffer, IPC_BUFFER_SIZE, &ret, &ipc->ol);
err = GetLastError();
if (!ok) {
if (err == ERROR_IO_PENDING) {
- readpending = TRUE;
+ ipc->readpending = TRUE;
return 0;
} else if (err == ERROR_BROKEN_PIPE) {
write_log ("IPC: IPC client disconnected\n");
} else {
write_log ("IPC: ReadFile() err=%d\n", err);
}
- resetIPC();
+ resetIPC(ipc);
return 0;
}
}
- readpending = FALSE;
- write_log ("IPC: got message '%s'\n", buffer);
- parsemessage((char*)buffer, p, (char*)outbuf, sizeof outbuf);
- memset (&ol, 0, sizeof ol);
- ol.hEvent = olevent;
- ok = WriteFile(hipc, outbuf, strlen ((char*)outbuf) + 1, &ret, &ol);
- err = GetLastError();
- if (!ok && err != ERROR_IO_PENDING) {
- write_log ("IPC: WriteFile() err=%d\n", err);
- resetIPC();
- return 0;
+ ipc->readpending = FALSE;
+ if (ipc->binary) {
+
+ } else {
+ write_log ("IPC: got message '%s'\n", ipc->buffer);
+ parsemessage((char*)ipc->buffer, p, (char*)ipc->outbuf, sizeof ipc->outbuf);
+ memset (&ipc->ol, 0, sizeof (OVERLAPPED));
+ ipc->ol.hEvent = ipc->olevent;
+ ok = WriteFile(ipc->hipc, ipc->outbuf, strlen ((char*)ipc->outbuf) + 1, &ret, &ipc->ol);
+ err = GetLastError();
+ if (!ok && err != ERROR_IO_PENDING) {
+ write_log ("IPC: WriteFile() err=%d\n", err);
+ resetIPC(ipc);
+ return 0;
+ }
+ ipc->writepending = TRUE;
}
- writepending = TRUE;
return 1;
}
+int isIPC (const char *pipename)
+{
+ HANDLE *p;
+
+ p = CreateFile(
+ pipename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (p == INVALID_HANDLE_VALUE)
+ return 0;
+ CloseHandle (p);
+ return 1;
+}