From: Toni Wilen Date: Sat, 30 Sep 2017 16:32:07 +0000 (+0300) Subject: Cubo updates. X-Git-Tag: 3600~93 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=8c7abbda60306afbcec18f3b7417743a37f045e3;p=francis%2Fwinuae.git Cubo updates. --- diff --git a/akiko.cpp b/akiko.cpp index 8505b78f..e12fe33f 100644 --- 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 05c2d05a..de9af4ac 100644 --- 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) + diff --git a/arcadia.cpp b/arcadia.cpp index 5aa2ec97..b44a9c63 100644 --- a/arcadia.cpp +++ b/arcadia.cpp @@ -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 * * */ @@ -23,6 +25,12 @@ #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); +} diff --git a/devices.cpp b/devices.cpp index 6b8ccb8a..29954300 100644 --- a/devices.cpp +++ b/devices.cpp @@ -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 } diff --git a/expansion.cpp b/expansion.cpp index 915d055e..21a16190 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -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, + }, { diff --git a/include/arcadia.h b/include/arcadia.h index 6ef31068..aee7d65b 100644 --- a/include/arcadia.h +++ b/include/arcadia.h @@ -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 */ diff --git a/include/inputdevice.h b/include/inputdevice.h index 232d84b2..1a9a9ba3 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -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 diff --git a/include/options.h b/include/options.h index 5119abb5..1d76404b 100644 --- a/include/options.h +++ b/include/options.h @@ -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; diff --git a/include/rommgr.h b/include/rommgr.h index 69f03a88..4f9401c5 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -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 diff --git a/inputdevice.cpp b/inputdevice.cpp index 878ffcce..573f7aa8 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -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); - } -} diff --git a/inputevents.def b/inputevents.def index aac56185..f6428ad3 100644 --- a/inputevents.def +++ b/inputevents.def @@ -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) diff --git a/memory.cpp b/memory.cpp index 7d7e94ac..f856a93e 100644 --- a/memory.cpp +++ b/memory.cpp @@ -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 diff --git a/od-win32/serial_win32.cpp b/od-win32/serial_win32.cpp index 69a9efc0..1e581dda 100644 --- a/od-win32/serial_win32.cpp +++ b/od-win32/serial_win32.cpp @@ -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; diff --git a/rommgr.cpp b/rommgr.cpp index 3e0bf423..11dc993a 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -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;