From: Toni Wilen Date: Sat, 29 Nov 2008 17:59:54 +0000 (+0200) Subject: imported winuaesrc1540b3.zip X-Git-Tag: 2100~109 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f9a037c5d04627eeb7f23ed08e94391a5417def5;p=francis%2Fwinuae.git imported winuaesrc1540b3.zip --- diff --git a/custom.c b/custom.c index 41fa57d2..b49574c9 100755 --- a/custom.c +++ b/custom.c @@ -218,7 +218,7 @@ int sprite_buffer_res; 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]; @@ -777,7 +777,7 @@ static uae_u32 fetched_aga1[MAX_PLANES]; #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. @@ -829,6 +829,12 @@ static void record_color_change2 (int hpos, int regno, unsigned long value) 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) { @@ -871,6 +877,12 @@ static void copy_bpl_params (int pos) 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; } @@ -909,6 +921,7 @@ static void compute_toscr_delay (int hpos) { toscr_res = f_bplcon0_res; toscr_nr_planes = f_bplcon0_planes_limit; + toscr_nr_planes2 = f_bplcon0_planes; compute_toscr_delay_1 (); } @@ -928,7 +941,7 @@ STATIC_INLINE void fetch (int nr, int fm) 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: @@ -955,6 +968,8 @@ STATIC_INLINE void fetch (int nr, int fm) mod = bpl1mod; bplpt[nr] += mod; } + } else if (isocs7planes ()) { + fetched[nr] = bplxdat[nr]; } if (nr == 0) fetch_state = fetch_was_plane0; @@ -979,15 +994,15 @@ static void clear_fetchbuffer (uae_u32 *ptr, int nwords) 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; } } @@ -998,12 +1013,12 @@ STATIC_INLINE void toscr_3_ecs (int nbits) 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; @@ -1042,7 +1057,7 @@ STATIC_INLINE void toscr_3_aga (int nbits, int fm) 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; @@ -1057,7 +1072,7 @@ STATIC_INLINE void toscr_3_aga (int nbits, int fm) 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; @@ -2370,7 +2385,7 @@ static void reset_decisions (void) 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; @@ -3109,6 +3124,17 @@ static void BPLxPTL (int hpos, uae_u16 v, int num) //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)) @@ -3133,6 +3159,12 @@ static void BPLCON0 (int hpos, uae_u16 v) 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 @@ -3156,7 +3188,7 @@ static void BPLCON0 (int hpos, uae_u16 v) 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]; } @@ -3242,17 +3274,22 @@ static void BPL2MOD (int hpos, uae_u16 v) 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); } @@ -3359,6 +3396,11 @@ static void FMODE (uae_u16 v) calcdiw (); } +static void FNULL (uae_u16 v) +{ + +} + static void BLTADAT (uae_u16 v) { maybe_blit (current_hpos(), 0); @@ -5554,6 +5596,7 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n 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: @@ -5617,6 +5660,7 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n #ifdef AGA case 0x1FC: FMODE (value); break; #endif + case 0x1FE: FNULL (value); break; /* writing to read-only register causes read access */ default: @@ -5791,7 +5835,7 @@ uae_u8 *restore_custom (uae_u8 *src) 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 */ @@ -5945,7 +5989,7 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) 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 */ diff --git a/drawing.c b/drawing.c index 1d4edd2d..af352616 100755 --- a/drawing.c +++ b/drawing.c @@ -335,7 +335,7 @@ static int playfield_start, playfield_end; 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; @@ -355,6 +355,8 @@ static void pfield_init_linetoscr (void) 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; @@ -369,6 +371,10 @@ static void pfield_init_linetoscr (void) 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) @@ -411,13 +417,10 @@ static void pfield_init_linetoscr (void) 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) @@ -1097,17 +1100,17 @@ static void dummy_worker (int start, int stop) { } -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) { @@ -1641,13 +1644,7 @@ static void pfield_expand_dp_bplcon (void) 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); diff --git a/hardfile.c b/hardfile.c index 1be67eef..099f66be 100755 --- a/hardfile.c +++ b/hardfile.c @@ -338,15 +338,13 @@ int hdf_hd_open (struct hd_hardfiledata *hfd, const char *path, int blocksize, i 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; } @@ -455,7 +453,7 @@ int vhd_create (const char *name, uae_u64 size) 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); @@ -542,7 +540,8 @@ int vhd_create (const char *name, uae_u64 size) 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; diff --git a/include/cpummu.h b/include/cpummu.h index a5a41c87..25f3e316 100755 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -31,7 +31,7 @@ #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) diff --git a/include/drawing.h b/include/drawing.h index 52626ba6..b84c0277 100755 --- a/include/drawing.h +++ b/include/drawing.h @@ -228,8 +228,8 @@ struct decision { #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 diff --git a/include/options.h b/include/options.h index 96338736..a6a77221 100755 --- a/include/options.h +++ b/include/options.h @@ -257,6 +257,7 @@ struct uae_prefs { int m68k_speed; int cpu_model; + int mmu_model; int cpu060_revision; int fpu_model; int fpu_revision; @@ -330,6 +331,7 @@ struct uae_prefs { int win32_soundcard; int win32_norecyclebin; int win32_specialkey; + int win32_guikey; int win32_kbledmode; int curses_reverse_video; diff --git a/include/uaeipc.h b/include/uaeipc.h index af0762d3..5a26b48c 100755 --- a/include/uaeipc.h +++ b/include/uaeipc.h @@ -1,4 +1,10 @@ -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); diff --git a/newcpu.c b/newcpu.c index 9dc829fe..59153032 100755 --- a/newcpu.c +++ b/newcpu.c @@ -1136,7 +1136,8 @@ kludge_me_do: 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 diff --git a/od-win32/direct3d.c b/od-win32/direct3d.c index e114ff45..a31410c8 100755 --- a/od-win32/direct3d.c +++ b/od-win32/direct3d.c @@ -1384,11 +1384,13 @@ HDC D3D_getDC (HDC hdc) 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); diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index eb9e565c..c9077eb8 100755 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -620,7 +620,12 @@ DWORD DirectDraw_GetCurrentDepth (void) 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; @@ -631,6 +636,8 @@ int DirectDraw_SurfaceLock (void) } 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--; diff --git a/od-win32/filesys.asm b/od-win32/filesys.asm deleted file mode 100755 index 21b93a7d..00000000 --- a/od-win32/filesys.asm +++ /dev/null @@ -1,1354 +0,0 @@ - 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 diff --git a/od-win32/keyboard_win32.c b/od-win32/keyboard_win32.c index af86730e..881a0f09 100755 --- a/od-win32/keyboard_win32.c +++ b/od-win32/keyboard_win32.c @@ -356,9 +356,8 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) //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 ()) { @@ -369,7 +368,11 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) } else { code = AKS_ENTERGUI; } - break; + } + + switch (scancode) + { + case DIK_F12: case DIK_F11: if (currprefs.win32_ctrl_F11_is_quit) { if (ctrlpressed ()) diff --git a/od-win32/parser.c b/od-win32/parser.c index 30d1146d..ba405e45 100755 --- a/od-win32/parser.c +++ b/od-win32/parser.c @@ -48,6 +48,7 @@ #include "serial.h" #include "savestate.h" #include "ahidsound_new.h" +#include "uaeipc.h" #include #include @@ -1228,6 +1229,12 @@ int enumserialports(void) 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; } diff --git a/od-win32/serial_win32.c b/od-win32/serial_win32.c index 963ffe82..be908d1d 100755 --- a/od-win32/serial_win32.c +++ b/od-win32/serial_win32.c @@ -265,7 +265,7 @@ uae_u16 SERDATR (void) 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; diff --git a/od-win32/win32.c b/od-win32/win32.c index a7085380..3faf1691 100755 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -87,6 +87,7 @@ static OSVERSIONINFO osVersion; static SYSTEM_INFO SystemInfo; static int logging_started; static DWORD minidumpmode = MiniDumpNormal; +void *globalipc, *serialipc; int qpcdivisor = 0; int cpu_mmx = 1; @@ -1366,7 +1367,7 @@ void handle_events (void) rp_vsync (); #endif cnt = 0; - while (checkIPC (&currprefs)); + while (checkIPC (globalipc, &currprefs)); if (quit_program) break; } @@ -1374,7 +1375,7 @@ void handle_events (void) TranslateMessage (&msg); DispatchMessage (&msg); } - while (checkIPC (&currprefs)); + while (checkIPC (globalipc, &currprefs)); if (was_paused) { resumepaused (); sound_closed = 0; @@ -1941,6 +1942,7 @@ void target_default_options (struct uae_prefs *p, int type) 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; @@ -2014,6 +2016,8 @@ void target_save_options (struct zfile *f, struct uae_prefs *p) 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"); @@ -2064,6 +2068,7 @@ int target_parse_option (struct uae_prefs *p, char *option, char *value) || 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)); @@ -3516,13 +3521,15 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR #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 diff --git a/od-win32/win32.h b/od-win32/win32.h index 8a895228..620b353e 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #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 "" @@ -33,6 +33,7 @@ extern int manual_painting_needed; 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]; diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 60d18814..a898dd76 100755 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -658,6 +658,8 @@ void flush_screen (int a, int b) static uae_u8 *ddraw_dolock (void) { + if (dx_islost ()) + return 0; if (!DirectDraw_SurfaceLock ()) return 0; gfxvidinfo.bufmem = DirectDraw_GetSurfacePointer (); diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 2050b226..e386f012 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -8840,7 +8840,7 @@ static void updatejoyport (HWND hDlg) if (idx >= 0) idx += 2; else - idx = 0; + idx = 1; if (idx >= total) idx = 0; SendDlgItemMessage (hDlg, id, CB_SETCURSEL, idx, 0); @@ -11646,10 +11646,10 @@ static int GetSettings (int all_options, HWND hwnd) 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(); } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index cb0ea147..a4bd96d4 100755 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,23 @@ +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 -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 @@ -34,7 +53,7 @@ Beta 1: 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 @@ -143,7 +162,7 @@ Beta 2: - 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. diff --git a/traps.c b/traps.c index c298be23..9a777d70 100755 --- a/traps.c +++ b/traps.c @@ -161,8 +161,9 @@ void REGPARAM2 m68k_handle_trap (unsigned int trap_num, struct regstruct *regs) } } - } else + } else { write_log ("Illegal emulator trap %d\n", trap_num); + } } diff --git a/uaeipc.c b/uaeipc.c index ac097940..0e49d1b5 100755 --- a/uaeipc.c +++ b/uaeipc.c @@ -12,11 +12,22 @@ #include -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) { @@ -48,83 +59,85 @@ 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++; @@ -135,106 +148,142 @@ int createIPC(void) 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; +}