]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Cubo updates.
authorToni Wilen <twilen@winuae.net>
Sat, 30 Sep 2017 16:32:07 +0000 (19:32 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 30 Sep 2017 16:32:07 +0000 (19:32 +0300)
14 files changed:
akiko.cpp
aks.def
arcadia.cpp
devices.cpp
expansion.cpp
include/arcadia.h
include/inputdevice.h
include/options.h
include/rommgr.h
inputdevice.cpp
inputevents.def
memory.cpp
od-win32/serial_win32.cpp
rommgr.cpp

index 8505b78fe12b7a2b87b80e208525f36087857751..e12fe33fe68df10ed6db817636d8fed3a2f79f8c 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -29,6 +29,7 @@
 #include "newcpu.h"
 #include "flashrom.h"
 #include "debug.h"
+#include "rommgr.h"
 
 #define AKIKO_DEBUG_IO 1
 #define AKIKO_DEBUG_IO_CMD 1
@@ -57,33 +58,46 @@ static void irq (void)
 */
 
 static uae_u8 *cd32_nvram;
+static int cd32_nvram_size;
 static void *cd32_eeprom;
 static uae_u8 cd32_i2c_direction;
 static bool cd32_i2c_data_scl, cd32_i2c_data_sda;
-static struct zfile *flashfile;
+struct zfile *cd32_flashfile;
+extern uae_u8 *cubo_nvram;
 
 static void nvram_read (void)
 {
-       zfile_fclose(flashfile);
-       flashfile = NULL;
+       cubo_nvram = NULL;
+       zfile_fclose(cd32_flashfile);
+       cd32_flashfile = NULL;
        eeprom_free(cd32_eeprom);
        cd32_eeprom = NULL;
        cd32_i2c_data_scl = cd32_i2c_data_sda = true;
        cd32_i2c_direction = 0;
        if (!currprefs.cs_cd32nvram)
                return;
-       if (!cd32_nvram)
-               cd32_nvram = xmalloc(uae_u8, currprefs.cs_cd32nvram_size);
-       memset(cd32_nvram, 0, currprefs.cs_cd32nvram_size);
-       flashfile = zfile_fopen (currprefs.flashfile, _T("rb+"), ZFD_NORMAL);
-       if (!flashfile)
-               flashfile = zfile_fopen (currprefs.flashfile, _T("wb"), 0);
-       if (flashfile) {
-               int size = zfile_fread(cd32_nvram, 1, currprefs.cs_cd32nvram_size, flashfile);
-               if (size < currprefs.cs_cd32nvram_size)
-                       zfile_fwrite(cd32_nvram + size, 1, currprefs.cs_cd32nvram_size - size, flashfile);
-       }
-       cd32_eeprom = eeprom_new(cd32_nvram, currprefs.cs_cd32nvram_size, flashfile);
+       int maxlen = currprefs.cs_cd32nvram_size;
+       if (is_board_enabled(&currprefs, ROMTYPE_CUBO, 0))
+               maxlen += 2048 + 16;
+       if (!cd32_nvram || cd32_nvram_size != maxlen) {
+               xfree(cd32_nvram);
+               cd32_nvram = xmalloc(uae_u8, maxlen);
+       }
+       memset(cd32_nvram, 0, maxlen);
+       if (is_board_enabled(&currprefs, ROMTYPE_CUBO, 0)) {
+               cubo_nvram = cd32_nvram + currprefs.cs_cd32nvram_size;
+       }
+       cd32_flashfile = zfile_fopen (currprefs.flashfile, _T("rb+"), ZFD_NORMAL);
+       if (!cd32_flashfile)
+               cd32_flashfile = zfile_fopen (currprefs.flashfile, _T("wb"), 0);
+       if (cd32_flashfile) {
+               int size = zfile_fread(cd32_nvram, 1, currprefs.cs_cd32nvram_size, cd32_flashfile);
+               if (size == currprefs.cs_cd32nvram_size && maxlen > currprefs.cs_cd32nvram_size)
+                       size += zfile_fread(cubo_nvram, 1, maxlen - currprefs.cs_cd32nvram_size, cd32_flashfile);
+               if (size < maxlen)
+                       zfile_fwrite(cd32_nvram + size, 1, maxlen - size, cd32_flashfile);
+       }
+       cd32_eeprom = eeprom_new(cd32_nvram, currprefs.cs_cd32nvram_size, cd32_flashfile);
 }
 
 static void akiko_nvram_write (int offset, uae_u32 v)
@@ -1267,7 +1281,7 @@ void AKIKO_hsync_handler (void)
                        cdrom_seek_delay--;
                }
                framecounter += (float)maxvpos * vblank_hz / (75.0 * cdrom_speed);
-               if (currprefs.cd_speed == 0)
+               if (currprefs.cd_speed == 0 || currprefs.turbo_emulation)
                        framecounter = 1;
                framesync = true;
        }
diff --git a/aks.def b/aks.def
index 05c2d05a95ba145ad96f9252467d159dbf40ff9b..de9af4ac77d4d448461d2a6ba10af7d34e5d2c8c 100644 (file)
--- a/aks.def
+++ b/aks.def
@@ -124,12 +124,10 @@ AKS(QUALIFIER_SHIFT)
 AKS(QUALIFIER_CONTROL)
 AKS(QUALIFIER_ALT)
 AKS(QUALIFIER_WIN)
-AKS(CUBO1)
-AKS(CUBO2)
-AKS(CUBO3)
-AKS(CUBO4)
-AKS(CUBO5)
-AKS(CUBO6)
-AKS(CUBO7)
-AKS(CUBO8)
 AKS(CUBOTOUCH)
+AKS(CUBOTEST)
+AKS(CUBOCOIN1)
+AKS(CUBOCOIN2)
+AKS(CUBOCOIN3)
+AKS(CUBOCOIN4)
+
index 5aa2ec974331776fec91a08e4010d65b71cac43f..b44a9c6355b297a9a88b6eba735c04b93597e293 100644 (file)
@@ -1,9 +1,11 @@
 /*
 * UAE - The Un*x Amiga Emulator
 *
-* Arcadia emulation
+* Arcadia
+* American Laser games
+* Cubo
 *
-* Copyright 2005-2007 Toni Wilen
+* Copyright 2005-2017 Toni Wilen
 *
 *
 */
 #include "videograb.h"
 #include "xwin.h"
 #include "drawing.h"
+#include "statusline.h"
+#include "rommgr.h"
+#include "flashrom.h"
+
+#define CUBO_DEBUG 1
+
 
 /* supported roms
 *
@@ -494,10 +502,13 @@ int arcadia_map_banks (void)
 }
 
 void alg_vsync(void);
+void cubo_vsync(void);
 void arcadia_vsync (void)
 {
        if (alg_flag)
                alg_vsync();
+       if (cubo_enabled)
+               cubo_vsync();
 
        if (arcadia_bios) {
                static int cnt;
@@ -1015,21 +1026,35 @@ void alg_map_banks(void)
        ser_buf_offset = 0;
 }
 
+static TCHAR cubo_pic_settings[ROMCONFIG_CONFIGTEXT_LEN];
+static uae_u32 cubo_settings;
+
 #define TOUCH_BUFFER_SIZE 10
 static int touch_buf_offset, touch_write_buf_offset;
 static int touch_cmd_active;
 static uae_u8 touch_data[TOUCH_BUFFER_SIZE + 1];
 static uae_u8 touch_data_w[TOUCH_BUFFER_SIZE];
 static int touch_active;
-extern uae_u16 cubo_flag;
+extern uae_u32 cubo_flag;
+
+static int ts_width_mult = 853;
+static int ts_width_offset = -73;
+static int ts_height_mult = 895;
+static int ts_height_offset = -8;
 
 int touch_serial_write(void)
 {
+       if (!(cubo_settings & 0x40000))
+               return -1;
+
        if (!touch_write_buf_offset && touch_active) {
-               if ((cubo_flag & 0x8000) && !(cubo_flag & 0x4000)) {
+               if ((cubo_flag & 0x80000000) && !(cubo_flag & 0x40000000)) {
                        uae_u8 *p = touch_data_w;
-                       int x = (lightpen_x[0] * 999) / gfxvidinfo.drawbuffer.inwidth;
-                       int y = (lightpen_y[0] * 999) / gfxvidinfo.drawbuffer.inheight;
+                       int sw = gfxvidinfo.drawbuffer.inwidth * ts_width_mult / 1000;
+                       int sh = gfxvidinfo.drawbuffer.inheight * ts_height_mult / 1000;
+
+                       int x = ((lightpen_x[0] + ts_width_offset) * 999) / sw;
+                       int y = ((lightpen_y[0] + ts_height_offset) * 999) / sh;
 
                        if (x < 0)
                                x = 0;
@@ -1042,6 +1067,9 @@ int touch_serial_write(void)
 
                        write_log(_T("%d*%d\n"), x, y);
 
+                       // y-coordinate is inverted
+                       y = 999 - y;
+
                        *p++ = 0x01;
                        sprintf((char*)p, "%03d", x);
                        p += 3;
@@ -1051,7 +1079,7 @@ int touch_serial_write(void)
                        *p++ = 0x0d;
                        touch_write_buf_offset = p - touch_data_w;
 
-                       cubo_flag |= 0x4000;
+                       cubo_flag |= 0x40000000;
                }
 
        }
@@ -1071,11 +1099,13 @@ static void touch_command_do(void)
        xfree(s);
 
        if (!memcmp(touch_data, "MDU", 3))
-               touch_active = 1;
+               touch_active = 1; // mode up/down
        if (!memcmp(touch_data, "MP", 2))
-               touch_active = 2;
+               touch_active = 2; // mode point (single per touchdown)
+       if (!memcmp(touch_data, "MS", 2))
+               touch_active = 3; // mode stream (continuous)
        if (!memcmp(touch_data, "MI", 2))
-               touch_active = 0;
+               touch_active = 0; // mode inactive
 
        // just respond "ok" to all commands..
        touch_data_w[0] = 0x01;
@@ -1086,17 +1116,22 @@ static void touch_command_do(void)
 
 void touch_serial_read(uae_u16 w)
 {
+       if (!(cubo_settings & 0x40000))
+               return;
+
        w &= 0xff;
        if (!touch_cmd_active) {
                if (w == 0x01) {
                        touch_cmd_active = 1;
                        touch_buf_offset = 0;
                }
-       } else {
+       }
+       else {
                if (w == 0x0d) {
                        touch_command_do();
                        touch_cmd_active = 0;
-               } else {
+               }
+               else {
                        if (touch_buf_offset < TOUCH_BUFFER_SIZE) {
                                touch_data[touch_buf_offset++] = (uae_u8)w;
                                touch_data[touch_buf_offset] = 0;
@@ -1104,3 +1139,496 @@ void touch_serial_read(uae_u16 w)
                }
        }
 }
+
+
+static const uae_u8 cubo_pic_secret_base[] = {
+       0x7c, 0xf9, 0x56, 0xf7, 0x58, 0x18, 0x22, 0x54, 0x38, 0xcd, 0x3d, 0x94, 0x09, 0xe6, 0x8e, 0x0d,
+       0x9a, 0x86, 0xfc, 0x1c, 0xa0, 0x19, 0x8f, 0xbc, 0xfd, 0x8d, 0xd1, 0x57, 0x56, 0xf2, 0xb6, 0x4f
+};
+static uae_u8 cubo_pic_byte, cubo_pic_bit_cnt, cubo_io_pic;
+static uae_u8 cubo_pic_key[2 + 8];
+static uae_u32 cubo_key;
+static bool cubo_pic_bit_cnt_changed;
+static uae_u8 cubo_pic_secret[32];
+
+static void calculate_key(uae_u8 key, int *idxp, uae_u8 *out)
+{
+       int idx = *idxp;
+       out[idx] ^= key;
+       uae_u8 b = cubo_pic_secret[out[idx] >> 4];
+       uae_u8 c = cubo_pic_secret[(out[idx] & 15) + 16];
+       c = ~(c + b);
+       c = (c << 1) | (c >> 7);
+       c += key;
+       c = (c << 1) | (c >> 7);
+       c = (c >> 4) | (c << 4);
+       idx++;
+       idx &= 3;
+       out[idx] ^= c;
+       *idxp = idx;
+}
+
+static char *get_bytes_from_string(const TCHAR *s)
+{
+       char *ds = xcalloc(char, _tcslen(s) + 1);
+       char *ss = ua(s);
+       char *sss = ss;
+       char *sp = ds;
+       while (*sss) {
+               char c = *sss++;
+               if (c == ':')
+                       break;
+               if (c == ' ')
+                       continue;
+               if (c == '\\') {
+                       if (*sss) {
+                               char *endptr = sss;
+                               *sp++ = (uae_u8)strtol(sss, &endptr, 16);
+                               sss = endptr;
+                       }
+                       continue;
+               }
+               *sp++ = c;
+       }
+       *sp = 0;
+       xfree(ss);
+       return ds;
+}
+
+static uae_u32 cubo_calculate_secret(uae_u8 *key)
+{
+       uae_u8 out[4] = { 0, 0, 0, 0 };
+       memcpy(cubo_pic_secret, cubo_pic_secret_base, sizeof(cubo_pic_secret));
+       TCHAR *s = cubo_pic_settings;
+       TCHAR *s2 = _tcschr(s, ':');
+       if (s2) {
+               s2++;
+               char *cs = get_bytes_from_string(s2);
+               if (cs) {
+                       memcpy(cubo_pic_secret, cs, strlen(cs));
+                       xfree(cs);
+               }
+       }
+       int idx = 0;
+       for (int i = 0; i < 8; i++) {
+               calculate_key(key[i], &idx, out);
+               calculate_key(key[i], &idx, out);
+       }
+       uae_u32 v = (out[0] << 24) | (out[1] << 16) | (out[2] << 8) | (out[3] << 0);
+       return v;
+}
+
+static uae_u8 cubo_read_pic(void)
+{
+       if (!(cubo_io_pic & 0x40))
+               return 0;
+       uae_u8 c = 0;
+       if (cubo_pic_bit_cnt >= 10 * 8) {
+               // return calculated 32-bit key
+               int offset = (cubo_pic_bit_cnt - (10 * 8)) / 8;
+               c = (cubo_key >> ((3 - offset) * 8)) & 0xff;
+       } else if (cubo_pic_bit_cnt < 8) {
+               struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CUBO, 0, NULL);
+               if (brc && brc->roms[0].configtext[0]) {
+                       char *cs = get_bytes_from_string(brc->roms[0].configtext);
+                       if (cs && strlen(cs) >= 2) {
+                               c = cs[0];
+                       }
+                       xfree(cs);
+               }
+       } else {
+               struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CUBO, 0, NULL);
+               if (brc && brc->roms[0].configtext[0]) {
+                       char *cs = get_bytes_from_string(brc->roms[0].configtext);
+                       if (cs && strlen(cs) >= 2) {
+                               c = cs[1];
+                       }
+                       xfree(cs);
+               }
+       }
+       uae_u8 v = 0;
+       if ((1 << (7 - (cubo_pic_bit_cnt & 7))) & c) {
+               v |= 4;
+       }
+       if (cubo_pic_bit_cnt_changed && (cubo_pic_bit_cnt & 7) == 7) {
+               write_log(_T("PIC sent %02x (%c)\n"), c, c);
+       }
+       cubo_pic_bit_cnt_changed = false;
+       return v;
+}
+
+static int cubo_message;
+
+static void cubo_write_pic(uae_u8 v)
+{
+       uae_u8 old = cubo_io_pic;
+       if ((v & 0x40) && !(cubo_io_pic & 0x40)) {
+               write_log(_T("Cubo PIC reset.\n"));
+               cubo_pic_bit_cnt = -1;
+       }
+       cubo_io_pic = v;
+
+       if (!(v & 0x40)) {
+               return;
+       }
+
+       if (!(old & 0x02) && (v & 0x02)) {
+               cubo_pic_bit_cnt++;
+               cubo_pic_bit_cnt_changed = true;
+               cubo_pic_byte <<= 1;
+               if (v & 0x08)
+                       cubo_pic_byte |= 1;
+               if ((cubo_pic_bit_cnt & 7) == 7) {
+                       int offset = cubo_pic_bit_cnt / 8;
+                       if (offset <= sizeof(cubo_pic_key)) {
+                               cubo_pic_key[offset] = cubo_pic_byte;
+                               write_log(_T("Cubo PIC received %02x (%d/%d)\n"), cubo_pic_byte, offset, sizeof(cubo_pic_key));
+                       }
+                       if (offset == sizeof(cubo_pic_key) - 1) {
+                               write_log(_T("Cubo PIC key in: "), cubo_key);
+                               for (int i = 0; i < 8; i++) {
+                                       write_log(_T("%02x "), cubo_pic_key[i + 2]);
+                               }
+                               write_log(_T("\n"));
+                               cubo_key = cubo_calculate_secret(cubo_pic_key + 2);
+                               write_log(_T("Cubo PIC key out: %02x.%02x.%02x.%02x\n"),
+                                       (cubo_key >> 24) & 0xff, (cubo_key >> 16) & 0xff,
+                                       (cubo_key >> 8) & 0xff, (cubo_key >> 0) & 0xff);
+                       }
+               }
+       }
+}
+
+static void *cubo_rtc;
+uae_u8 *cubo_nvram;
+static uae_u8 cubo_rtc_byte;
+extern struct zfile *cd32_flashfile;
+
+#define CUBO_NVRAM_SIZE 2048
+#define CUBO_RTC_SIZE 16
+
+static void cubo_read_rtc(void)
+{
+       if (!cubo_nvram)
+               return;
+       
+       uae_u8 *r = &cubo_nvram[CUBO_NVRAM_SIZE];
+       struct timeval tv;
+       static int prevs100;
+       
+       gettimeofday(&tv, NULL);
+       time_t t = tv.tv_sec;
+       t += currprefs.cs_rtc_adjust;
+       struct tm *ct = localtime(&t);
+
+       bool h24 = (r[4] & 0x80) == 0;
+       bool mask = (r[0] & 0x08) != 0;
+
+       int h = ct->tm_hour;
+       if (h24) {
+               r[4] = (h % 10) | ((h / 10) << 4);
+       } else {
+               r[4] &= ~0x40;
+               if (h > 12) {
+                       h -= 12;
+                       r[4] |= 0x40;
+               }
+               r[4] = (h % 10) | ((h / 10) << 4);
+       }
+       r[4] &= ~0x80;
+       r[4] |= h24 ? 0x80 : 0x00;
+
+       r[5] = (r[5] & 0xc0) | (ct->tm_mday % 10) | ((ct->tm_mday / 10) << 4);
+
+       r[6] = (ct->tm_wday << 5) | ((ct->tm_mon + 1) % 10) | (((ct->tm_mon + 1) / 10) << 4);
+
+       int s100 = tv.tv_usec / 10000;
+       if (s100 == prevs100) {
+               s100++;
+               s100 %= 1000000;
+       }
+       prevs100 = s100;
+
+       r[1] = (s100 % 10) | ((s100 / 10) << 4);
+
+       r[2] = (ct->tm_sec % 10) | ((ct->tm_sec / 10) << 4);
+
+       r[3] = (ct->tm_min % 10) | ((ct->tm_min / 10) << 4);
+
+       r[4] = (ct->tm_hour % 10) | ((ct->tm_hour / 10) << 4);
+
+       if (cd32_flashfile) {
+               zfile_fseek(cd32_flashfile, currprefs.cs_cd32nvram_size + CUBO_NVRAM_SIZE, SEEK_SET);
+               zfile_fwrite(r, 1, CUBO_RTC_SIZE, cd32_flashfile);
+       }
+
+}
+
+static void cubo_rtc_write(uae_u8 addr, uae_u8 v)
+{
+       uae_u8 *r = &cubo_nvram[CUBO_NVRAM_SIZE];
+       addr &= CUBO_RTC_SIZE - 1;
+       if (addr == 0) {
+               if ((v & 0x40) && !(r[0] & 0x40)) {
+                       cubo_read_rtc();
+               }
+               r[addr] = v;
+       } else if (addr == 5) {
+               // 2 year bits are writable
+               r[addr] &= 0x3f;
+               r[addr] |= v & 0xc0;
+       } else if (addr >= 7) {
+               // timer registers are writable
+               r[addr] = v;
+       }
+       write_log(_T("CUBO RTC write %08x %02x\n"), addr, v);
+
+       if (cd32_flashfile) {
+               zfile_fseek(cd32_flashfile, currprefs.cs_cd32nvram_size + CUBO_NVRAM_SIZE + addr, SEEK_SET);
+               zfile_fwrite(&v, 1, 1, cd32_flashfile);
+       }
+}
+static uae_u8 cubo_rtc_read(uae_u8 addr)
+{
+       uae_u8 *r = &cubo_nvram[CUBO_NVRAM_SIZE];
+       bool mask = (r[0] & 0x08) != 0;
+       addr &= CUBO_RTC_SIZE - 1;
+       uae_u8 v = r[addr];
+       if (mask) {
+               if (addr == 5)
+                       v &= 0x3f;
+               if (addr == 6)
+                       v &= 0x1f;
+       }
+       write_log(_T("CUBO RTC read %08x %02x\n"), addr, v);
+       return v;
+}
+
+static void cubo_write_rtc(uae_u8 v)
+{
+       // bit 5 = data
+       // bit 6 = enable?
+       // bit 7 = clock
+
+       cubo_rtc_byte = v;
+
+       if (!(v & 0x40)) {
+               i2c_reset(cubo_rtc);
+               return;
+       }
+
+       int sda = (v & 0x20) ? 1 : 0;
+       int scl = (v & 0x80) ? 1 : 0;
+
+       i2c_set(cubo_rtc, BITBANG_I2C_SDA, sda);
+       i2c_set(cubo_rtc, BITBANG_I2C_SCL, scl);
+}
+
+static uae_u8 cubo_vars[4];
+
+
+static uae_u32 REGPARAM2 cubo_get(uaecptr addr)
+{
+       uae_u8 v = 0;
+
+       addr -= 0x00600000;
+       addr &= 0x003fffff;
+       addr += 0x00600000;
+
+       if (addr >= 0x600000 && addr < 0x600000 + 0x2000 && (addr & 3) == 0) {
+               if (cubo_settings & 0x10000) {
+                       int offset = (addr - 0x600000) / 4;
+                       if (cubo_nvram)
+                               v = cubo_nvram[offset];
+               }
+#if CUBO_DEBUG > 1
+               write_log(("CUBO_GET NVRAM %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+       } else if (addr == 0x00800003) {
+               // DIP switch #1
+               // #1 = coin 3 (0->1)
+               // #8 = coin 1 (0->1)
+               v = (uae_u8)cubo_settings;
+               // Test button clears DIP 8 (but lets just toggle here)
+               if (cubo_flag & 0x00800000) {
+                       v ^= 0x0080;
+               }
+
+               v ^= (cubo_flag & 0x00ff) >> 0;
+
+#if CUBO_DEBUG > 2
+               write_log(("CUBO_GET D1 %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+       } else if (addr == 0x00800013) {
+               // DIP switch #2
+               // #1 = coin 4 (0->1)
+               // #8 = coin 2 (0->1)
+               v = (uae_u8)(cubo_settings >> 8);
+
+               // bits 4 and 5 have something to do with hopper
+
+               if (cubo_pic_settings[0]) {
+                       // bit 2 (0x04) is PIC data
+                       if (cubo_io_pic & 0x40) {
+                               v &= ~0x04;
+                               v |= cubo_read_pic();
+                       }
+               }
+               // bit 6 (0x40) is I2C SDA
+               if ((cubo_settings & 0x20000) && cubo_rtc && (cubo_rtc_byte & 0x40)) {
+                       v &= ~0x40;
+                       if (eeprom_i2c_set(cubo_rtc, BITBANG_I2C_SDA, -1)) {
+                               v |= 0x40;
+                       }
+               }
+
+               v ^= (cubo_flag & 0xff00) >> 8;
+
+#if CUBO_DEBUG > 2
+               write_log(("CUBO_GET D2/PIC %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+
+       } else {
+#if CUBO_DEBUG
+               write_log(("CUBO_GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+       }
+       return v;
+}
+
+static void REGPARAM2 cubo_put(uaecptr addr, uae_u32 v)
+{
+       addr -= 0x00600000;
+       addr &= 0x003fffff;
+       addr += 0x00600000;
+
+       v &= 0xff;
+
+       if (addr >= 0x600000 && addr < 0x600000 + 0x2000 && (addr & 3) == 0) {
+               if (cubo_settings & 0x10000) {
+                       int offset = (addr - 0x600000) / 4;
+#if CUBO_DEBUG > 1
+                       write_log(("CUBO_PUT NVRAM %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+                       if (cubo_nvram) {
+                               cubo_nvram[offset] = v;
+                               if (cd32_flashfile) {
+                                       zfile_fseek(cd32_flashfile, currprefs.cs_cd32nvram_size + offset, SEEK_SET);
+                                       zfile_fwrite(&v, 1, 1, cd32_flashfile);
+                               }
+                       }
+               }
+       } else if (addr == 0x0080000b) {
+               if (cubo_pic_settings[0]) {
+                       // PIC communication uses bits 1 (0x02 "clock"), 3 (0x08 "data"), 6 (0x40 enable)
+#if CUBO_DEBUG > 2
+                       write_log(("CUBO_PUT PIC %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+                       cubo_write_pic(v);
+               }
+               if ((v & (0x80 | 0x04)) && !(cubo_message & 1)) {
+                       // bits 2 and 7 are used by hopper
+                       cubo_message |= 1;
+                       statusline_add_message(STATUSTYPE_OTHER, _T("Unemulated Hopper bits set."));
+               }
+       } else if (addr == 0x0080001b) {
+#if CUBO_DEBUG > 2
+               write_log(("CUBO_PUT RTC %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+               if (cubo_settings & 0x20000) {
+                       cubo_write_rtc(v);
+               }
+               // bit 4 = suzo
+               if ((v & (0x10)) && !(cubo_message & 2)) {
+                       cubo_message |= 2;
+                       statusline_add_message(STATUSTYPE_OTHER, _T("Unemulated Suzo bits set."));
+               }
+       } else {
+#if CUBO_DEBUG
+               write_log(("CUBO_PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+       }
+}
+
+static uae_u8 dip_delay[16];
+
+void cubo_function(int v)
+{
+       int c = -1;
+       switch (v)
+       {
+       case 0:
+               c = 7;
+               break;
+       case 1:
+               c = 15;
+               break;
+       case 2:
+               c = 0;
+               break;
+       case 3:
+               c = 8;
+               break;
+       }
+       if (c < 0 || dip_delay[c])
+               return;
+       dip_delay[c] = 5;
+}
+
+void cubo_vsync(void)
+{
+       for (int i = 0; i < 16; i++) {
+               if (dip_delay[i] >= 3) {
+                       cubo_flag |= 1 << i;
+               } else if (dip_delay[i] > 0) {
+                       cubo_flag &= ~(1 << i);
+               }
+               if (dip_delay[i] > 0)
+                       dip_delay[i]--;
+       }
+}
+
+
+static addrbank cubo_bank = {
+       cubo_get, cubo_get, cubo_get,
+       cubo_put, cubo_put, cubo_put,
+       default_xlate, default_check, NULL, NULL, _T("CUBO"),
+       dummy_lgeti, dummy_wgeti, ABFLAG_RAM, S_READ, S_WRITE,
+       NULL, 0x3fffff, 0x600000, 0x600000
+};
+
+bool cubo_init(struct autoconfig_info *aci)
+{
+       aci->start = 0x00600000;
+       aci->size  = 0x00400000;
+       if (!aci->doinit)
+               return true;
+       map_banks(&cubo_bank, aci->start >> 16, aci->size >> 16, 0);
+       aci->addrbank = &cubo_bank;
+       return true;
+}
+
+void arcadia_reset(void)
+{
+       cubo_enabled = is_board_enabled(&currprefs, ROMTYPE_CUBO, 0);
+       i2c_free(cubo_rtc);
+       cubo_rtc = i2c_new(0xa2, CUBO_RTC_SIZE, cubo_rtc_read, cubo_rtc_write);
+       cubo_read_rtc();
+       cubo_message = 0;
+       cubo_rtc_byte = 0;
+       cubo_settings = 0;
+       cubo_pic_settings[0] = 0;
+}
+
+void check_arcadia_prefs_changed(void)
+{
+       if (!config_changed)
+               return;
+       board_prefs_changed(ROMTYPE_CUBO, 0);
+       cubo_enabled = is_board_enabled(&currprefs, ROMTYPE_CUBO, 0);
+       struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CUBO, 0, NULL);
+       if (!brc)
+               return;
+       cubo_settings = brc->roms[0].device_settings;
+       _tcscpy(cubo_pic_settings, brc->roms[0].configtext);
+}
index 6b8ccb8ae33a0232caf10fbf2395f220d29878a8..29954300cfefe529aa18472a48945fd2d59fd8d8 100644 (file)
@@ -60,6 +60,8 @@
 #include "ethernet.h"
 #include "drawing.h"
 #include "videograb.h"
+#include "arcadia.h"
+#include "rommgr.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -72,6 +74,7 @@ void device_check_config(void)
        check_prefs_changed_cpu();
        check_prefs_picasso();
        check_prefs_changed_gayle();
+       check_arcadia_prefs_changed();
 }
 
 void devices_reset(int hardreset)
@@ -118,6 +121,9 @@ void devices_reset(int hardreset)
 #endif
        ethernet_reset();
        uae_int_requested = 0;
+#ifdef ARCADIA
+       arcadia_reset();
+#endif
 }
 
 
index 915d055eeb3ff7ed66765d3a9526753bf1226e66..21a161909600642ab70eeabc280470718ceaa8a8 100644 (file)
@@ -46,6 +46,7 @@
 #include "filesys.h"
 #include "ethernet.h"
 #include "sana2.h"
+#include "arcadia.h"
 
 
 #define CARD_FLAG_CAN_Z3 1
@@ -3813,6 +3814,7 @@ static const struct expansionsubromtype a2090_sub[] = {
        }
 };
 #endif
+
 static const struct expansionsubromtype a2091_sub[] = {
        {
                _T("DMAC-01"), _T("dmac01"), 0,
@@ -3926,6 +3928,7 @@ static const struct expansionsubromtype mediator_sub[] = {
                NULL
        }
 };
+
 static const struct expansionboardsettings mediator_settings[] = {
        {
                _T("Full PCI DMA"),
@@ -4166,6 +4169,93 @@ static const struct expansionboardsettings harlequin_settings[] = {
        }
 };
 
+static const struct expansionboardsettings cubo_settings[] = {
+       {
+               _T("DIP1 #1"),
+               _T("dip_1_1")
+       },
+       {
+               _T("DIP1 #2"),
+               _T("dip_1_2")
+       },
+       {
+               _T("DIP1 #3"),
+               _T("dip_1_3")
+       },
+       {
+               _T("DIP1 #4"),
+               _T("dip_1_4")
+       },
+       {
+               _T("DIP1 #5"),
+               _T("dip_1_5")
+       },
+       {
+               _T("DIP1 #6"),
+               _T("dip_1_6")
+       },
+       {
+               _T("DIP1 #7"),
+               _T("dip_1_7")
+       },
+       {
+               _T("DIP1 #8"),
+               _T("dip_1_8")
+       },
+       {
+               _T("DIP2 #1"),
+               _T("dip_2_1")
+       },
+       {
+               _T("DIP2 #2"),
+               _T("dip_2_2")
+       },
+       {
+               _T("DIP2 #3"),
+               _T("dip_2_3")
+       },
+       {
+               _T("DIP2 #4"),
+               _T("dip_2_4")
+       },
+       {
+               _T("DIP2 #5"),
+               _T("dip_2_5")
+       },
+       {
+               _T("DIP2 #6)"),
+               _T("dip_2_6")
+       },
+       {
+               _T("DIP2 #7 "),
+               _T("dip_2_7")
+       },
+       {
+               _T("DIP2 #8"),
+               _T("dip_2_8")
+       },
+       {
+               _T("NVRAM installed"),
+               _T("nvram")
+       },
+       {
+               _T("RTC installed"),
+               _T("rtc")
+       },
+       {
+               _T("Touchscreen installed"),
+               _T("ts")
+       },
+       {
+               _T("PIC configuration (AB:KEY)\0"),
+               _T("pic\0"),
+               2, false, 0
+       },
+       {
+               NULL
+       }
+};
+
 static struct expansionboardsettings ne2k_isa_settings[] = {
        {
                _T("IO\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
@@ -5249,6 +5339,14 @@ const struct expansionromtype expansionroms[] = {
                NULL, 0,
                false, EXPANSIONTYPE_CUSTOM
        },
+       {
+               _T("cubo"), _T("Cubo CD32"), NULL,
+               NULL, cubo_init, NULL, NULL, ROMTYPE_CUBO | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_CUSTOM,
+               0, 0, 0, false, NULL,
+               false, 0, cubo_settings,
+       },
 
 
        {
index 6ef31068a97dbe94444c1a1cb1cfb8691fa530c8..aee7d65b4a2d2a17191dbf1bbdbf349fe2dcc028 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef ARCADIA
 
+extern void arcadia_reset(void);
+
 extern int is_arcadia_rom (const TCHAR *path);
 extern int arcadia_map_banks (void);
 extern void arcadia_unmap (void);
@@ -42,6 +44,12 @@ extern int cubo_enabled;
 extern void touch_serial_read(uae_u16 w);
 extern int touch_serial_write(void);
 
+extern bool cubo_init(struct autoconfig_info *aci);
+
+extern void check_arcadia_prefs_changed(void);
+
+extern void cubo_function(int);
+
 #endif /* ARCADIA */
 
 #endif /* UAE_ARCADIA_H */
index 232d84b2b6e3e72e265fba3c167f308d7c8b9028..1a9a9ba3abbf1fa1fcafa0debf746810a1533085 100644 (file)
@@ -325,7 +325,6 @@ extern int inputdevice_get_lightpen_id(void);
 extern uae_u64 input_getqualifiers (void);
 
 extern void setsystime (void);
-extern void inputdevice_map(void);
 
 #define JSEM_MODE_DEFAULT 0
 #define JSEM_MODE_WHEELMOUSE 1
index 5119abb5a6e10f185de085fb90509fbad69004d1..1d76404b18ea109351bf7f17f3d90469a64fa787 100644 (file)
@@ -585,7 +585,6 @@ struct uae_prefs {
        bool cs_cd32c2p;
        bool cs_cd32nvram;
        bool cs_cd32fmv;
-       bool cs_cd32cubo;
        int cs_cd32nvram_size;
        bool cs_cdtvcd;
        bool cs_cdtvram;
index 69f03a88ebdabe1f30a9159343c349841d2e19ea..4f9401c523b7e440f052324fb1c645ea5603e9d2 100644 (file)
@@ -158,6 +158,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_FASTATA4K      0x00100068
 #define ROMTYPE_INMATE         0x00100069
 #define ROMTYPE_EMPLANT                0x0010006a
+#define ROMTYPE_CUBO           0x0010006b
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
@@ -256,6 +257,7 @@ void clear_device_rom(struct uae_prefs *p, int romtype, int devnum, bool deleteD
 struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index);
 bool is_board_enabled(struct uae_prefs *p, int romtype, int devnum);
 void board_prefs_changed(int romtype, int devnum);
+void check_board_prefs_changed(void);
 
 #define LOADROM_FILL 1
 #define LOADROM_EVENONLY 2
index 878ffcce7decd73924ecab1e07012d196d246e92..573f7aa8a2ccf9f0cc9da038d7dc84af338e277b 100644 (file)
@@ -371,7 +371,7 @@ static int analog_port[NORMAL_JPORTS][2];
 static int digital_port[NORMAL_JPORTS][2];
 static int lightpen_port[NORMAL_JPORTS];
 int cubo_enabled;
-uae_u16 cubo_flag;
+uae_u32 cubo_flag;
 #define POTDAT_DELAY_PAL 8
 #define POTDAT_DELAY_NTSC 7
 
@@ -4138,28 +4138,34 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s)
                        arcadia_coin[1]++;
                break;
 
-       case AKS_CUBO1:
-       case AKS_CUBO2:
-       case AKS_CUBO3:
-       case AKS_CUBO4:
-       case AKS_CUBO5:
-       case AKS_CUBO6:
-       case AKS_CUBO7:
-       case AKS_CUBO8:
-       {
-               int idx = code - AKS_CUBO1;
-               if (state) {
-                       cubo_flag ^= 1 << idx;
-                       write_log(_T("Cubo flag = %02x\n"), cubo_flag & 0xff);
-               }
-               break;
-       }
        case AKS_CUBOTOUCH:
                if (state)
-                       cubo_flag |= 0x8000;
+                       cubo_flag |= 0x80000000;
+               else
+                       cubo_flag &= ~0x80000000;
+               cubo_flag &= ~0x40000000;
+               break;
+       case AKS_CUBOTEST:
+               if (state)
+                       cubo_flag |= 0x00800000;
                else
-                       cubo_flag &= ~0x8000;
-               cubo_flag &= ~0x4000;
+                       cubo_flag &= ~0x00800000;
+               break;
+       case AKS_CUBOCOIN1:
+               if (state)
+                       cubo_function(0);
+               break;
+       case AKS_CUBOCOIN2:
+               if (state)
+                       cubo_function(1);
+               break;
+       case AKS_CUBOCOIN3:
+               if (state)
+                       cubo_function(2);
+               break;
+       case AKS_CUBOCOIN4:
+               if (state)
+                       cubo_function(3);
                break;
 
        case AKS_ALGSERVICE:
@@ -5041,7 +5047,7 @@ void inputdevice_vsync (void)
        if (mouseedge_alive > 0)
                mouseedge_alive--;
 #ifdef ARCADIA
-       if (arcadia_bios || alg_flag)
+       if (arcadia_bios || alg_flag || cubo_enabled)
                arcadia_vsync ();
 #endif
        if (mouseedge ())
@@ -5728,10 +5734,6 @@ static int iscd32 (int ei)
                cd32_pad_enabled[1] = 1;
                return 2;
        }
-       if (ei >= INPUTEVENT_SPC_CUBO_SW1 && ei <= INPUTEVENT_SPC_CUBO_TOUCH) {
-               cubo_enabled = 1;
-               return 3;
-       }
        return 0;
 }
 
@@ -8356,8 +8358,17 @@ void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int
 static void clearpressmask(void)
 {
        for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
-               joysticks2[i].buttonmask = 0;
+               for (int j = 0; j < 32; j++) {
+                       uae_u32 mask = 1 << j;
+                       if (joysticks2[i].buttonmask & mask) {
+                               setbuttonstateall(&joysticks[i], &joysticks2[i], j, 0);
+                       }
+                       if (mice2[i].buttonmask & mask) {
+                               setbuttonstateall(&mice[i], &mice2[i], j, 0);
+                       }
+               }
                mice2[i].buttonmask = 0;
+               joysticks2[i].buttonmask = 0;
        }
 }
 
@@ -8405,8 +8416,6 @@ void inputdevice_acquire (int allmode)
        //    if (!input_acquired)
        //      write_log (_T("input devices acquired (%s)\n"), allmode ? "all" : "selected only");
        input_acquired = 1;
-
-       inputdevice_map();
 }
 
 void inputdevice_unacquire(bool emulationactive, int inputmask)
@@ -9407,42 +9416,3 @@ void clear_inputstate (void)
                relativecount[i][0] = relativecount[i][1] = 0;
        }
 }
-
-#define CUBO_DEBUG 0
-
-static uae_u32 REGPARAM2 cubo_get(uaecptr addr)
-{
-       addr &= 0xffff;
-       if (addr == 3) {
-#if CUBO_DEBUG
-               write_log(("%08x %02x %08x\n"), addr, cubo_flag, M68K_GETPC);
-#endif
-               return cubo_flag;
-       }
-#if CUBO_DEBUG
-       write_log(("%08x %08x\n"), addr, M68K_GETPC);
-#endif
-       return 0;
-}
-static void REGPARAM2 cubo_put(uaecptr addr, uae_u32 v)
-{
-#if CUBO_DEBUG
-       write_log(("%08x %08x %08x\n"), addr, v, M68K_GETPC);
-#endif
-}
-
-static addrbank cubo_bank = {
-       cubo_get, cubo_get, cubo_get,
-       cubo_put, cubo_put, cubo_put,
-       default_xlate, default_check, NULL, NULL, _T("CUBO"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_RAM, S_READ, S_WRITE,
-       NULL, 65536
-};
-
-void inputdevice_map(void)
-{
-       if ((cubo_enabled || currprefs.cs_cd32cubo) && get_mem_bank_real(0x00800000) == &dummy_bank) {
-               write_log(_T("Cubo CD32 enabled\n"));
-               map_banks(&cubo_bank, 0x00800000 >> 16, 1, 0);
-       }
-}
index aac56185ee4f048a8cc16558fce7bbdd9ee7de3f..f6428ad3b82108895bec0c3691f7bcc1333bc492 100644 (file)
@@ -425,15 +425,12 @@ DEFEVENT(SPC_ALG_RTRIGGER,_T("American Laser Games Right Trigger"),AM_K,0,0,AKS_
 DEFEVENT(SPC_ALG_LHOLSTER,_T("American Laser Games Left Holster"),AM_K,0,0,AKS_ALGLHOLSTER)
 DEFEVENT(SPC_ALG_RHOLSTER,_T("American Laser Games Right Holster"),AM_K,0,0,AKS_ALGRHOLSTER)
 
-DEFEVENT(SPC_CUBO_SW1,_T("Cubo CD32 Switch #1"),AM_K,0,0,AKS_CUBO1)
-DEFEVENT(SPC_CUBO_SW2,_T("Cubo CD32 Switch #2"),AM_K,0,0,AKS_CUBO2)
-DEFEVENT(SPC_CUBO_SW3,_T("Cubo CD32 Switch #3"),AM_K,0,0,AKS_CUBO3)
-DEFEVENT(SPC_CUBO_SW4,_T("Cubo CD32 Switch #4"),AM_K,0,0,AKS_CUBO4)
-DEFEVENT(SPC_CUBO_SW5,_T("Cubo CD32 Switch #5"),AM_K,0,0,AKS_CUBO5)
-DEFEVENT(SPC_CUBO_SW6,_T("Cubo CD32 Switch #6"),AM_K,0,0,AKS_CUBO6)
-DEFEVENT(SPC_CUBO_SW7,_T("Cubo CD32 Switch #7"),AM_K,0,0,AKS_CUBO7)
-DEFEVENT(SPC_CUBO_SW8,_T("Cubo CD32 Switch #8"),AM_K,0,0,AKS_CUBO8)
 DEFEVENT(SPC_CUBO_TOUCH,_T("Cubo CD32 Touchscreen touch"),AM_K,0,0,AKS_CUBOTOUCH)
+DEFEVENT(SPC_CUBO_TEST,_T("Cubo CD32 Test"),AM_K,0,0,AKS_CUBOTEST)
+DEFEVENT(SPC_CUBO_COIN1,_T("Cubo CD32 coin player 1"),AM_K,0,0,AKS_CUBOCOIN1)
+DEFEVENT(SPC_CUBO_COIN2,_T("Cubo CD32 coin player 2"),AM_K,0,0,AKS_CUBOCOIN2)
+DEFEVENT(SPC_CUBO_COIN3,_T("Cubo CD32 coin player 3"),AM_K,0,0,AKS_CUBOCOIN3)
+DEFEVENT(SPC_CUBO_COIN4,_T("Cubo CD32 coin player 4"),AM_K,0,0,AKS_CUBOCOIN4)
 
 DEFEVENT(SPC_CDTV_FRONT_PANEL_STOP,_T("CDTV Front Panel Stop"),AM_K,0,0,AKS_CDTV_FRONT_PANEL_STOP)
 DEFEVENT(SPC_CDTV_FRONT_PANEL_PLAYPAUSE,_T("CDTV Front Panel Play/Pause"),AM_K,0,0,AKS_CDTV_FRONT_PANEL_PLAYPAUSE)
index 7d7e94ac837f35f08b01e862de2c0b5af4251528..f856a93e8182ab5d7822e152a018b2bdacdb9a94 100644 (file)
@@ -1868,7 +1868,7 @@ bool mapped_malloc (addrbank *ab)
        if (!md.directsupport || (ab->flags & ABFLAG_ALLOCINDIRECT)) {
                if (!(ab->flags & ABFLAG_ALLOCINDIRECT)) {
                        if (canbang) {
-                               write_log(_T("JIT direct switched off: %s\n"), ab->name);
+                               error_log(_T("JIT direct switched off: %s\n"), ab->name);
                        }
                        nocanbang();
                }
@@ -2658,7 +2658,6 @@ void memory_reset (void)
                arcadia_map_banks ();
        }
 #endif
-       inputdevice_map();
 
 #ifdef ACTION_REPLAY
 #ifdef ARCADIA
index 69a9efc01bba6274fc5f701220a92c94052f8102..1e581dda862afac6f61cd2cf3a58a244cd781270 100644 (file)
@@ -393,7 +393,7 @@ static void checksend(void)
                ld_serial_read(serdatshift);
        }
 #endif
-       if (currprefs.cs_cd32cubo || cubo_enabled) {
+       if (cubo_enabled) {
                touch_serial_read(serdatshift);
        }
 #ifdef SERIAL_MAP
@@ -536,7 +536,7 @@ void serial_hsynchandler (void)
                }
        }
 #endif
-       if ((currprefs.cs_cd32cubo || cubo_enabled) && !data_in_serdatr) {
+       if (cubo_enabled && !data_in_serdatr) {
                int ch = touch_serial_write();
                if (ch >= 0) {
                        serdatr = ch | 0x100;
index 3e0bf4234440f02cb2d625d36945cfd41e2d7873..11dc993a99e12d0bc4ec1e3b92eedf33c51f7b1a 100644 (file)
@@ -2158,7 +2158,8 @@ struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devn
 {
        const struct expansionromtype *ert = get_device_expansion_rom(romtype);
        if (!ert) {
-               *index = 0;
+               if (index)
+                       *index = 0;
                return NULL;
        }
        int parentrom = ert->parentromtype ? ert->parentromtype : romtype;