return NULL;
}
+static void validatefsname (TCHAR *name, int isdevname)
+{
+ int i;
+ for (i = 0; i < _tcslen (name); i++) {
+ if (name[i] == ':')
+ name[i] = 0;
+ if (name[i] == '/')
+ name[i] = 0;
+ }
+}
+
struct uaedev_config_info *add_filesys_config (struct uae_prefs *p, int index,
TCHAR *devname, TCHAR *volname, TCHAR *rootdir, int readonly,
int secspertrack, int surfaces, int reserved,
int blocksize, int bootpri,
- TCHAR *filesysdir, int hdc, int flags) {
- struct uaedev_config_info *uci;
- int i;
- TCHAR *s;
+ TCHAR *filesysdir, int hdc, int flags)
+{
+ struct uaedev_config_info *uci;
+ int i;
+ TCHAR *s;
- if (index < 0) {
- uci = getuci(p);
- uci->configoffset = -1;
- } else {
- uci = &p->mountconfig[index];
+ if (devname && _tcslen (devname) > 0) {
+ for (i = 0; i < p->mountitems; i++) {
+ if (p->mountconfig[i].devname && !_tcscmp (p->mountconfig[i].devname, devname))
+ return 0;
}
- if (!uci)
- return 0;
- uci->ishdf = volname == NULL ? 1 : 0;
- _tcscpy (uci->devname, devname ? devname : L"");
- _tcscpy (uci->volname, volname ? volname : L"");
- _tcscpy (uci->rootdir, rootdir ? rootdir : L"");
- uci->readonly = readonly;
- uci->sectors = secspertrack;
- uci->surfaces = surfaces;
- uci->reserved = reserved;
- uci->blocksize = blocksize;
- uci->bootpri = bootpri;
- uci->donotmount = 0;
- uci->autoboot = 0;
- if (bootpri < -128)
- uci->donotmount = 1;
- else if (bootpri >= -127)
- uci->autoboot = 1;
- uci->controller = hdc;
- _tcscpy (uci->filesys, filesysdir ? filesysdir : L"");
- if (!uci->devname[0]) {
- TCHAR base[32];
- TCHAR base2[32];
- int num = 0;
- if (uci->rootdir[0] == 0 && !uci->ishdf)
- _tcscpy (base, L"RDH");
- else
- _tcscpy (base, L"DH");
- _tcscpy (base2, base);
- for (i = 0; i < p->mountitems; i++) {
- _stprintf (base2, L"%s%d", base, num);
- if (!_tcscmp(base2, p->mountconfig[i].devname)) {
- num++;
- i = -1;
- continue;
- }
+ }
+
+ if (index < 0) {
+ uci = getuci(p);
+ uci->configoffset = -1;
+ } else {
+ uci = &p->mountconfig[index];
+ }
+ if (!uci)
+ return 0;
+
+ uci->ishdf = volname == NULL ? 1 : 0;
+ _tcscpy (uci->devname, devname ? devname : L"");
+ _tcscpy (uci->volname, volname ? volname : L"");
+ _tcscpy (uci->rootdir, rootdir ? rootdir : L"");
+ validatefsname (uci->devname, 1);
+ validatefsname (uci->volname, 0);
+ uci->readonly = readonly;
+ uci->sectors = secspertrack;
+ uci->surfaces = surfaces;
+ uci->reserved = reserved;
+ uci->blocksize = blocksize;
+ uci->bootpri = bootpri;
+ uci->donotmount = 0;
+ uci->autoboot = 0;
+ if (bootpri < -128)
+ uci->donotmount = 1;
+ else if (bootpri >= -127)
+ uci->autoboot = 1;
+ uci->controller = hdc;
+ _tcscpy (uci->filesys, filesysdir ? filesysdir : L"");
+ if (!uci->devname[0]) {
+ TCHAR base[32];
+ TCHAR base2[32];
+ int num = 0;
+ if (uci->rootdir[0] == 0 && !uci->ishdf)
+ _tcscpy (base, L"RDH");
+ else
+ _tcscpy (base, L"DH");
+ _tcscpy (base2, base);
+ for (i = 0; i < p->mountitems; i++) {
+ _stprintf (base2, L"%s%d", base, num);
+ if (!_tcscmp(base2, p->mountconfig[i].devname)) {
+ num++;
+ i = -1;
+ continue;
}
- _tcscpy (uci->devname, base2);
}
- s = filesys_createvolname (volname, rootdir, L"Harddrive");
- _tcscpy (uci->volname, s);
- xfree (s);
- return uci;
+ _tcscpy (uci->devname, base2);
+ validatefsname (uci->devname, 1);
+ }
+ s = filesys_createvolname (volname, rootdir, L"Harddrive");
+ _tcscpy (uci->volname, s);
+ xfree (s);
+ return uci;
}
static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num)
static int last_decide_line_hpos, last_sprite_decide_line_hpos;
static int last_fetch_hpos, last_sprite_hpos;
static int diwfirstword, diwlastword;
+static int plfleft_real;
static enum diw_states diwstate, hdiwstate, ddfstate;
int first_planes_vpos, last_planes_vpos;
int diwfirstword_total, diwlastword_total;
}
/* Expand bplcon0/bplcon1 into the toscr_xxx variables. */
-static void compute_toscr_delay_1 (void)
+static void compute_toscr_delay_1 (int bplcon1)
{
int delay1 = (bplcon1 & 0x0f) | ((bplcon1 & 0x0c00) >> 6);
int delay2 = ((bplcon1 >> 4) & 0x0f) | (((bplcon1 >> 4) & 0x0c00) >> 6);
toscr_delay2 |= shdelay2 >> (RES_MAX - toscr_res);
}
-static void compute_toscr_delay (int hpos)
+static void compute_toscr_delay (int hpos, int bplcon1)
{
update_denise (hpos);
- compute_toscr_delay_1 ();
+ compute_toscr_delay_1 (bplcon1);
+}
+
+STATIC_INLINE void clear_fetchbuffer (uae_u32 *ptr, int nwords)
+{
+ int i;
+
+ if (! thisline_changed) {
+ for (i = 0; i < nwords; i++) {
+ if (ptr[i]) {
+ thisline_changed = 1;
+ break;
+ }
+ }
+ }
+ memset (ptr, 0, nwords * 4);
+}
+
+static void update_toscr_planes (void)
+{
+ if (toscr_nr_planes2 > thisline_decision.nr_planes) {
+ int 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);
+ thisline_decision.nr_planes = toscr_nr_planes2;
+ }
}
STATIC_INLINE void maybe_first_bpl1dat (int hpos)
{
- if (thisline_decision.plfleft == -1) {
- thisline_decision.plfleft = hpos;
+ if (thisline_decision.plfleft != -1) {
+ // early bpl1day crap fix (Sequential engine animation)
+ if (plfleft_real == -1) {
+ int i;
+ for (i = 0; i < thisline_decision.nr_planes; i++) {
+ todisplay[i][0] = 0;
+#ifdef AGA
+ todisplay[i][1] = 0;
+ todisplay[i][2] = 0;
+ todisplay[i][3] = 0;
+#endif
+ }
+ plfleft_real = hpos;
+ bpl1dat_early = 1;
+ }
+ } else {
+ plfleft_real = thisline_decision.plfleft = hpos;
compute_delay_offset ();
}
}
}
}
-static void clear_fetchbuffer (uae_u32 *ptr, int nwords)
-{
- int i;
-
- if (! thisline_changed) {
- for (i = 0; i < nwords; i++) {
- if (ptr[i]) {
- thisline_changed = 1;
- break;
- }
- }
- }
- memset (ptr, 0, nwords * 4);
-}
-
-static void update_toscr_planes (void)
-{
- if (toscr_nr_planes2 > thisline_decision.nr_planes) {
- int 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);
- thisline_decision.nr_planes = toscr_nr_planes2;
- }
-}
-
STATIC_INLINE void toscr_3_ecs (int nbits)
{
int delay1 = toscr_delay1;
{
int i;
int oleft = thisline_decision.plfleft;
+ static uae_u16 bplcon1t, bplcon1t2;
flush_display (fm);
update_denise (hpos);
maybe_first_bpl1dat (hpos);
+ bplcon1t2 = bplcon1t;
+ bplcon1t = bplcon1;
// writing to BPLCON1 1 cycle after BPL1DAT access will
// not (except first BPL1DAT write) affect the display
// until next display block
if (bplcon1_hpos != hpos || oleft < 0)
- compute_toscr_delay (hpos);
+ bplcon1t2 = bplcon1t;
+ compute_toscr_delay (hpos, bplcon1t2);
}
#ifdef SPEEDUP
if (thisline_decision.plfleft == -1) {
compute_delay_offset ();
- compute_toscr_delay_1 ();
+ compute_toscr_delay_1 (bplcon1);
}
do_long_fetch (pos, count >> (3 - toscr_res), dma, fm);
thisline_decision.bplres = bplcon0_res;
ddfstate = DIW_waiting_stop;
- compute_toscr_delay (last_fetch_hpos);
+ compute_toscr_delay (last_fetch_hpos, bplcon1);
/* If someone already wrote BPL1DAT, clear the area between that point and
the real fetch start. */
bpl1dat_written = 0;
bpl1dat_early = 0;
+ plfleft_real = -1;
thisline_decision.plfleft = -1;
thisline_decision.plflinelen = -1;
thisline_decision.ham_seen = !! (bplcon0 & 0x800);
if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
isntsc = currprefs.ntscmode ? 1 : 0;
if (hack_vpos > 0) {
- if (maxvpos == hack_vpos)
+ if (maxvpos == hack_vpos) {
+ hack_vpos = -1;
return;
+ }
maxvpos = hack_vpos;
vblank_hz = 15600 / hack_vpos;
hack_vpos = -1;
bplxdat[num] = v;
if (num == 0) {
bpl1dat_written = 1;
- if (thisline_decision.plfleft == -1)
- bpl1dat_early = 1;
- maybe_first_bpl1dat (hpos);
+ if (thisline_decision.plfleft == -1) {
+ thisline_decision.plfleft = hpos;
+ compute_delay_offset ();
+ }
}
}
-#define TD_PADX 10
+#define TD_PADX 4
#define TD_PADY 2
-#define TD_WIDTH 32
+#define TD_WIDTH 30
#define TD_LED_WIDTH 24
#define TD_LED_HEIGHT 4
#ifdef SERIAL_ENET
static ENetHost *enethost, *enetclient;
-static ENetPeer *enetpeer;
+static ENetPeer *enetpeer, *enet;
static int enetmode;
+static uae_u16 enet_receive[256];
+static int enet_receive_off_w, enet_receive_off_r;
+
+static void enet_service (int serveronly)
+{
+ ENetEvent evt;
+ ENetAddress address;
+ int got;
+
+ if (enetmode == 0)
+ return;
+
+ got = 1;
+ while (got) {
+ got = 0;
+ if (enetmode > 0) {
+ while (enet_host_service (enethost, &evt, 0)) {
+ got = 1;
+ switch (evt.type)
+ {
+ case ENET_EVENT_TYPE_CONNECT:
+ address = evt.peer->address;
+ write_log (L"ENET_SERVER: connect from %d.%d.%d.%d:%u\n",
+ (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff,
+ address.port);
+ evt.peer->data = 0;
+ break;
+ case ENET_EVENT_TYPE_RECEIVE:
+ {
+ uae_u8 *p = evt.packet->data;
+ int len = evt.packet->dataLength;
+ if (len == 6 && !strncmp (p, "UAE_", 4)) {
+ if (((enet_receive_off_w + 1) & 0xff) != enet_receive_off_r) {
+ enet_receive[enet_receive_off_w++] = (p[4] << 8) | p[5];
+ }
+ }
+
+ enet_packet_destroy (evt.packet);
+ }
+ break;
+ case ENET_EVENT_TYPE_DISCONNECT:
+ address = evt.peer->address;
+ write_log (L"ENET_SERVER: disconnect from %d.%d.%d.%d:%u\n",
+ (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff,
+ address.port);
+ break;
+ }
+ }
+ }
+ if (!serveronly) {
+ while (enet_host_service (enetclient, &evt, 0)) {
+ got = 1;
+ switch (evt.type)
+ {
+ default:
+ write_log (L"ENET_CLIENT: %d\n", evt.type);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void enet_disconnect (ENetPeer *peer)
+{
+ ENetEvent evt;
+ int cnt = 30;
+
+ if (!peer)
+ return;
+
+ write_log (L"ENET_CLIENT: disconnecting..\n");
+ enet_peer_disconnect (peer, 0);
+ while (cnt-- > 0) {
+ enet_service (1);
+ while (enet_host_service (enetclient, &evt, 100) > 0)
+ {
+ switch (evt.type)
+ {
+ case ENET_EVENT_TYPE_RECEIVE:
+ enet_packet_destroy (evt.packet);
+ break;
+
+ case ENET_EVENT_TYPE_DISCONNECT:
+ write_log (L"ENET_CLIENT: disconnection succeeded\n");
+ enetpeer = NULL;
+ return;
+ }
+ }
+ }
+ write_log (L"ENET_CLIENT: disconnection forced\n");
+ enet_peer_reset (enetpeer);
+ enetpeer = NULL;
+}
void enet_close (void)
{
- if (enethost)
- enet_host_destroy (enethost);
- enethost = NULL;
+ enet_disconnect (enetpeer);
if (enetclient)
enet_host_destroy (enetclient);
enetclient = NULL;
+ if (enethost)
+ enet_host_destroy (enethost);
+ enethost = NULL;
+ serial_enet = 0;
+ enetmode = 0;
}
int enet_open (TCHAR *name)
{
ENetAddress address;
+ ENetPacket *p;
static int initialized;
+ uae_u8 data[16];
+ int cnt;
if (!initialized) {
int err = enet_initialize ();
enet_close ();
enetmode = 0;
- if (!_tcsnicmp (name, L"ENET:L", 6)) {
- enetclient = enet_host_create (NULL, 1, 0, 0);
- if (enetclient == NULL) {
- write_log (L"ENET: enet_host_create(client) failed\n");
- return 0;
- }
- write_log (L"ENET: client created\n");
- enet_address_set_host (&address, "192.168.0.10");
- address.port = 1234;
- enetpeer = enet_host_connect (enetclient, &address, 2);
- if (enetpeer == NULL) {
- write_log (L"ENET: connection to host failed\n");
- enet_host_destroy (enetclient);
- enetclient = NULL;
- }
- write_log (L"ENET: connection initialized\n");
- enetmode = -1;
- return 1;
- } else if (!_tcsnicmp (name, L"ENET:H", 6)) {
+ if (!_tcsnicmp (name, L"ENET:H", 6)) {
address.host = ENET_HOST_ANY;
address.port = 1234;
enethost = enet_host_create (&address, 2, 0, 0);
if (enethost == NULL) {
- write_log (L"ENET: enet_host_create(server) failed\n");
+ write_log (L"ENET_SERVER: enet_host_create(server) failed\n");
+ enet_close ();
return 0;
}
- write_log (L"ENET: server created\n");
- enet_address_set_host (&address, "127.0.0.1");
- address.port = 1234;
- enetpeer = enet_host_connect (enethost, &address, 2);
- if (enetpeer == NULL) {
- write_log (L"ENET: connection to localhost failed\n");
- enet_host_destroy (enetclient);
- enetclient = NULL;
- }
- write_log (L"ENET: local connection initialized\n");
+ write_log (L"ENET_SERVER: server created\n");
enetmode = 1;
- return 1;
+ } else {
+ enetmode = -1;
+ }
+ enetclient = enet_host_create (NULL, 1, 0, 0);
+ if (enetclient == NULL) {
+ write_log (L"ENET_CLIENT: enet_host_create(client) failed\n");
+ enet_close ();
+ return 0;
+ }
+ write_log (L"ENET_CLIENT: client created\n");
+ enet_address_set_host (&address, enetmode > 0 ? "127.0.0.1" : "192.168.0.10");
+ address.port = 1234;
+ enetpeer = enet_host_connect (enetclient, &address, 2);
+ if (enetpeer == NULL) {
+ write_log (L"ENET_CLIENT: connection to host %d.%d.%d.%d:%d failed\n",
+ (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port);
+ enet_host_destroy (enetclient);
+ enetclient = NULL;
+ }
+ write_log (L"ENET_CLIENT: connecting to %d.%d.%d.%d:%d...\n",
+ (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port);
+ cnt = 10 * 5;
+ while (cnt-- > 0) {
+ ENetEvent evt;
+ enet_service (0);
+ if (enet_host_service (enetclient, &evt, 100) > 0) {
+ if (evt.type == ENET_EVENT_TYPE_CONNECT)
+ break;
+ }
+ }
+ if (cnt <= 0) {
+ write_log (L"ENET_CLIENT: connection failed, no response in 5 seconds\n");
+ enet_close ();
+ return 0;
}
- return 0;
+ strcpy (data, "UAE_HELLO");
+ p = enet_packet_create (data, sizeof data, ENET_PACKET_FLAG_RELIABLE);
+ enet_peer_send (enetpeer, 0, p);
+ enet_host_flush (enetclient);
+ write_log (L"ENET: connected\n");
+ serial_enet = 1;
+ return 1;
}
void enet_writeser (uae_u16 w)
strcpy (data, "UAE_");
data[4] = w >> 8;
data[5] = w >> 0;
+ write_log (L"W=%04X ", w);
p = enet_packet_create (data, 6, ENET_PACKET_FLAG_RELIABLE);
enet_peer_send (enetpeer, 0, p);
+ enet_host_flush (enetclient);
}
-static uae_u16 enet_receive[256];
-static int enet_receive_off_w, enet_receive_off_r;
-
int enet_readseravail (void)
{
- ENetEvent evt;
- ENetHost *host;
-
- if (enetmode == 0)
- return 0;
- host = enetmode < 0 ? enetclient : enethost;
- while (enet_host_service (host, &evt, 0)) {
- switch (evt.type)
- {
- case ENET_EVENT_TYPE_CONNECT:
- write_log (L"ENET: connect from %x:%u\n",
- evt.peer->address.host, evt.peer->address.port);
- evt.peer->data = 0;
- break;
- case ENET_EVENT_TYPE_RECEIVE:
- {
- uae_u8 *p = evt.packet->data;
- int len = evt.packet->dataLength;
- write_log (L"ENET: packet received, %d bytes\n", len);
- if (len == 6) {
- if (((enet_receive_off_w + 1) & 0xff) != enet_receive_off_r) {
- enet_receive[enet_receive_off_w++] = (p[4] << 8) | p[5];
- }
- }
-
- enet_packet_destroy (evt.packet);
- }
- break;
- case ENET_EVENT_TYPE_DISCONNECT:
- write_log (L"ENET: disconnect %p\n", evt.peer->data);
- break;
- }
- }
- return 0;
+ enet_service (0);
+ return enet_receive_off_r != enet_receive_off_w;
}
+
int enet_readser (uae_u16 *data)
{
if (enet_receive_off_r == enet_receive_off_w)
return 0;
*data = enet_receive[enet_receive_off_r++];
+ write_log (L"R=%04X ", *data);
enet_receive_off_r &= 0xff;
return 1;
}
#define WINUAEPUBLICBETA 1
-#define WINUAEBETA L"21"
-#define WINUAEDATE MAKEBD(2009, 11, 15)
+#define WINUAEBETA L"22"
+#define WINUAEDATE MAKEBD(2009, 11, 21)
#define WINUAEEXTRA L""
#define WINUAEREV L""
}
}
-static void fixvol (TCHAR *s)
-{
- if (_tcslen (s) == 0)
- return;
- if (s[_tcslen (s) - 1] == ':')
- s[_tcslen (s) - 1] = 0;
-}
-
static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int recursive = 0;
}
GetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir, sizeof current_fsvdlg.rootdir / sizeof (TCHAR));
GetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume, sizeof current_fsvdlg.volume / sizeof (TCHAR));
- fixvol (current_fsvdlg.volume);
GetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device, sizeof current_fsvdlg.device / sizeof (TCHAR));
- fixvol (current_fsvdlg.device);
current_fsvdlg.rw = IsDlgButtonChecked (hDlg, IDC_FS_RW);
current_fsvdlg.bootpri = GetDlgItemInt (hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE);
current_fsvdlg.autoboot = IsDlgButtonChecked (hDlg, IDC_FS_AUTOBOOT);
+Beta 22:
+
+- do not load multiple harddrives (directory and regular hardfile) from
+ configuration file if they have identical device names, also fixes
+ bad handling of hardrive paths with national characters in utf8
+- added simple validation to harddrive device and volume labels
+- fixed small graphics glitch in Sequential / Andromeda "18 frames!"
+- slightly smaller on screen leds, fits in 320 pixel wide display
+- "write to BPLCON1 immediately after BPL1DAT" handling was buggy, in
+ some cases bpl delay change had too long delay (Demo2 / Parasite)
+- KS 1.x interlace screen setup was incompatible with "scandoubler"
Beta 21: