From 9b35e764166d01d5ee2c51173ba4ad3b0274993d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Aug 2022 23:01:27 -0700 Subject: [PATCH 1/3] GB MBC: Add more TAMA6 commands --- include/mgba/internal/gb/memory.h | 2 ++ src/gb/mbc.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/mgba/internal/gb/memory.h b/include/mgba/internal/gb/memory.h index bc9199ffa..6e02ffa4d 100644 --- a/include/mgba/internal/gb/memory.h +++ b/include/mgba/internal/gb/memory.h @@ -138,6 +138,8 @@ enum GBTAMA6Command { GBTAMA6_HOUR_WRITE = 0x5, GBTAMA6_MINUTE_READ = 0x6, GBTAMA6_HOUR_READ = 0x7, + GBTAMA6_DISABLE_ALARM = 0x10, + GBTAMA6_ENABLE_ALARM = 0x11, }; enum GBHuC3Register { diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 5c7fb0310..4ff38a765 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -1719,6 +1719,18 @@ void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value) { tama5->rtcTimerPage[GBTAMA6_RTC_PA0_HOUR_1] = out & 0xF; tama5->rtcTimerPage[GBTAMA6_RTC_PA0_HOUR_10] = out >> 4; break; + case GBTAMA6_DISABLE_ALARM: + tama5->rtcTimerPage[GBTAMA6_RTC_PAGE] &= 0xB; + tama5->rtcAlarmPage[GBTAMA6_RTC_PAGE] &= 0xB; + tama5->rtcFreePage0[GBTAMA6_RTC_PAGE] &= 0xB; + tama5->rtcFreePage1[GBTAMA6_RTC_PAGE] &= 0xB; + break; + case GBTAMA6_ENABLE_ALARM: + tama5->rtcTimerPage[GBTAMA6_RTC_PAGE] |= 0x4; + tama5->rtcAlarmPage[GBTAMA6_RTC_PAGE] |= 0x4; + tama5->rtcFreePage0[GBTAMA6_RTC_PAGE] |= 0x4; + tama5->rtcFreePage1[GBTAMA6_RTC_PAGE] |= 0x4; + break; } break; case 0x4: // RTC access From c305c377db48ef2a45e9241adb9e553ae1a6a475 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 31 Aug 2022 00:12:10 -0700 Subject: [PATCH 2/3] GB MBC: Finish TAMA6 timer (non-alarm) emulation --- include/mgba/internal/gb/serialize.h | 3 ++ src/gb/mbc.c | 79 +++++++++++++++++++++------- src/gb/memory.c | 12 +++++ 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/include/mgba/internal/gb/serialize.h b/include/mgba/internal/gb/serialize.h index 52f1fe8aa..3ff904086 100644 --- a/include/mgba/internal/gb/serialize.h +++ b/include/mgba/internal/gb/serialize.h @@ -465,6 +465,9 @@ struct GBSerializedState { struct { uint8_t registers[8]; uint8_t rtcTimerPage[8]; + uint8_t rtcAlarmPage[8]; + uint8_t rtcFreePage0[8]; + uint8_t rtcFreePage1[8]; } tama5Registers; }; diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 4ff38a765..d6c39035c 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -17,6 +17,12 @@ const uint32_t GB_LOGO_HASH = 0x46195417; mLOG_DEFINE_CATEGORY(GB_MBC, "GB MBC", "gb.mbc"); +static const uint8_t _tama6RTCMask[32] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0xF, 0x7, 0xF, 0x7, 0xF, 0x3, 0x7, 0xF, 0x3, 0xF, 0x1, 0xF, 0xF, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xF, 0x7, 0xF, 0x3, 0x7, 0xF, 0x3, 0x0, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, +}; + static void _GBMBCNone(struct GB* gb, uint16_t address, uint8_t value) { UNUSED(address); UNUSED(value); @@ -1537,7 +1543,7 @@ static int _tama6DMYToDayOfYear(int day, int month, int year) { return -1; } day += _daysToMonth[month]; - if (month > 2 && (year % 4) == 0) { + if (month > 2 && (year & 3) == 0) { ++day; } return day; @@ -1549,7 +1555,7 @@ static int _tama6DayOfYearToMonth(int day, int year) { if (day <= _daysToMonth[month + 1]) { return month; } - if (month == 2 && year % 4 == 0) { + if (month == 2 && (year & 3) == 0) { if (day == 60) { return 2; } @@ -1565,7 +1571,7 @@ static int _tama6DayOfYearToDayOfMonth(int day, int year) { if (day <= _daysToMonth[month + 1]) { return day - _daysToMonth[month]; } - if (month == 2 && year % 4 == 0) { + if (month == 2 && (year & 3) == 0) { if (day == 60) { return 29; } @@ -1593,6 +1599,7 @@ static void _latchTAMA6Rtc(struct mRTCSource* rtc, struct GBTAMA5State* tama5, t } uint8_t* timerRegs = tama5->rtcTimerPage; + bool is24hour = tama5->rtcAlarmPage[GBTAMA6_RTC_PA1_24_HOUR]; int64_t diff; diff = timerRegs[GBTAMA6_RTC_PA0_SECOND_1] + timerRegs[GBTAMA6_RTC_PA0_SECOND_10] * 10 + t % 60; if (diff < 0) { @@ -1614,31 +1621,47 @@ static void _latchTAMA6Rtc(struct mRTCSource* rtc, struct GBTAMA5State* tama5, t t /= 60; t += diff / 60; - diff = timerRegs[GBTAMA6_RTC_PA0_HOUR_1] + timerRegs[GBTAMA6_RTC_PA0_HOUR_10] * 10 + t % 24; + diff = timerRegs[GBTAMA6_RTC_PA0_HOUR_1]; + if (is24hour) { + diff += timerRegs[GBTAMA6_RTC_PA0_HOUR_10] * 10; + } else { + int hour10 = timerRegs[GBTAMA6_RTC_PA0_HOUR_10]; + diff += (hour10 & 1) * 10; + diff += (hour10 & 2) * 12; + } + diff += t % 24; if (diff < 0) { diff += 24; t -= 24; } - timerRegs[GBTAMA6_RTC_PA0_HOUR_1] = (diff % 24) % 10; - timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 24) / 10; + if (is24hour) { + timerRegs[GBTAMA6_RTC_PA0_HOUR_1] = (diff % 24) % 10; + timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 24) / 10; + } else { + timerRegs[GBTAMA6_RTC_PA0_HOUR_1] = (diff % 12) % 10; + timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 12) / 10 + (diff / 12) * 2; + } t /= 24; t += diff / 24; int day = timerRegs[GBTAMA6_RTC_PA0_DAY_1] + timerRegs[GBTAMA6_RTC_PA0_DAY_10] * 10; int month = timerRegs[GBTAMA6_RTC_PA0_MONTH_1] + timerRegs[GBTAMA6_RTC_PA0_MONTH_10] * 10; int year = timerRegs[GBTAMA6_RTC_PA0_YEAR_1] + timerRegs[GBTAMA6_RTC_PA0_YEAR_10] * 10; - int dayInYear = _tama6DMYToDayOfYear(day, month, year); + int leapYear = tama5->rtcAlarmPage[GBTAMA6_RTC_PA1_LEAP_YEAR]; + int dayOfWeek = timerRegs[GBTAMA6_RTC_PA0_WEEK]; + int dayInYear = _tama6DMYToDayOfYear(day, month, leapYear); diff = dayInYear + t; while (diff <= 0) { // Previous year - if (year % 4) { + if (leapYear & 3) { diff += 365; } else { diff += 366; } --year; + --leapYear; } - while (diff > (year % 4 ? 365 : 366)) { + while (diff > (leapYear & 3 ? 365 : 366)) { // Future year if (year % 4) { diff -= 365; @@ -1646,11 +1669,17 @@ static void _latchTAMA6Rtc(struct mRTCSource* rtc, struct GBTAMA5State* tama5, t diff -= 366; } ++year; + ++leapYear; } + dayOfWeek = (dayOfWeek + diff) % 7; year %= 100; + leapYear &= 3; - day = _tama6DayOfYearToDayOfMonth(diff, year); - month = _tama6DayOfYearToMonth(diff, year); + day = _tama6DayOfYearToDayOfMonth(diff, leapYear); + month = _tama6DayOfYearToMonth(diff, leapYear); + + timerRegs[GBTAMA6_RTC_PA0_WEEK] = dayOfWeek; + tama5->rtcAlarmPage[GBTAMA6_RTC_PA1_LEAP_YEAR] = leapYear; timerRegs[GBTAMA6_RTC_PA0_DAY_1] = day % 10; timerRegs[GBTAMA6_RTC_PA0_DAY_10] = day / 10; @@ -1734,18 +1763,25 @@ void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value) { } break; case 0x4: // RTC access + address = tama5->registers[GBTAMA5_WRITE_LO]; + if (address >= GBTAMA6_RTC_PAGE) { + break; + } + out = tama5->registers[GBTAMA5_WRITE_HI]; switch (tama5->registers[GBTAMA5_ADDR_LO]) { case 0: - tama5->rtcTimerPage[out & 0xF] = out >> 4; + out &= _tama6RTCMask[address]; + tama5->rtcTimerPage[address] = out; break; case 2: - tama5->rtcAlarmPage[out & 0xF] = out >> 4; + out &= _tama6RTCMask[address | 0x10]; + tama5->rtcAlarmPage[address] = out; break; case 4: - tama5->rtcFreePage0[out & 0xF] = out >> 4; + tama5->rtcFreePage0[address] = out; break; case 6: - tama5->rtcFreePage1[out & 0xF] = out >> 4; + tama5->rtcFreePage1[address] = out; break; } break; @@ -1808,18 +1844,23 @@ uint8_t _GBTAMA5Read(struct GBMemory* memory, uint16_t address) { break; } _latchTAMA6Rtc(memory->rtc, tama5, &memory->rtcLastLatch); + address = tama5->registers[GBTAMA5_WRITE_LO]; + if (address > GBTAMA6_RTC_PAGE) { + value = 0; + break; + } switch (tama5->registers[GBTAMA5_ADDR_LO]) { case 1: - value = tama5->rtcTimerPage[tama5->registers[GBTAMA5_WRITE_LO]]; + value = tama5->rtcTimerPage[address]; break; case 3: - value = tama5->rtcTimerPage[tama5->registers[GBTAMA5_WRITE_LO]]; + value = tama5->rtcTimerPage[address]; break; case 5: - value = tama5->rtcTimerPage[tama5->registers[GBTAMA5_WRITE_LO]]; + value = tama5->rtcTimerPage[address]; break; case 7: - value = tama5->rtcTimerPage[tama5->registers[GBTAMA5_WRITE_LO]]; + value = tama5->rtcTimerPage[address]; break; } break; diff --git a/src/gb/memory.c b/src/gb/memory.c index b1a4f84ed..501ebe7a1 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -773,6 +773,12 @@ void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) { state->tama5Registers.registers[i] |= memory->mbcState.tama5.registers[i * 2 + 1] << 4; state->tama5Registers.rtcTimerPage[i] = memory->mbcState.tama5.rtcTimerPage[i * 2] & 0xF; state->tama5Registers.rtcTimerPage[i] |= memory->mbcState.tama5.rtcTimerPage[i * 2 + 1] << 4; + state->tama5Registers.rtcAlarmPage[i] = memory->mbcState.tama5.rtcAlarmPage[i * 2] & 0xF; + state->tama5Registers.rtcAlarmPage[i] |= memory->mbcState.tama5.rtcAlarmPage[i * 2 + 1] << 4; + state->tama5Registers.rtcFreePage0[i] = memory->mbcState.tama5.rtcFreePage0[i * 2] & 0xF; + state->tama5Registers.rtcFreePage0[i] |= memory->mbcState.tama5.rtcFreePage0[i * 2 + 1] << 4; + state->tama5Registers.rtcFreePage1[i] = memory->mbcState.tama5.rtcFreePage1[i * 2] & 0xF; + state->tama5Registers.rtcFreePage1[i] |= memory->mbcState.tama5.rtcFreePage1[i * 2 + 1] << 4; } break; case GB_HuC3: @@ -892,6 +898,12 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) { memory->mbcState.tama5.registers[i * 2 + 1] = state->tama5Registers.registers[i] >> 4; memory->mbcState.tama5.rtcTimerPage[i * 2] = state->tama5Registers.rtcTimerPage[i] & 0xF; memory->mbcState.tama5.rtcTimerPage[i * 2 + 1] = state->tama5Registers.rtcTimerPage[i] >> 4; + memory->mbcState.tama5.rtcAlarmPage[i * 2] = state->tama5Registers.rtcAlarmPage[i] & 0xF; + memory->mbcState.tama5.rtcAlarmPage[i * 2 + 1] = state->tama5Registers.rtcAlarmPage[i] >> 4; + memory->mbcState.tama5.rtcFreePage0[i * 2] = state->tama5Registers.rtcFreePage0[i] & 0xF; + memory->mbcState.tama5.rtcFreePage0[i * 2 + 1] = state->tama5Registers.rtcFreePage0[i] >> 4; + memory->mbcState.tama5.rtcFreePage1[i * 2] = state->tama5Registers.rtcFreePage1[i] & 0xF; + memory->mbcState.tama5.rtcFreePage1[i * 2 + 1] = state->tama5Registers.rtcFreePage1[i] >> 4; } break; case GB_HuC3: From c6b25f14a33695b71b55a4504949762d805af3c4 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Thu, 1 Sep 2022 11:16:45 +0200 Subject: [PATCH 3/3] Use reverse DNS for LInux data files (#2648) --- CMakeLists.txt | 18 +++++++++--------- res/mgba-qt.desktop | 2 +- src/platform/qt/CMakeLists.txt | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6a8ab221..f0c105964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -898,15 +898,15 @@ if(NOT SKIP_LIBRARY) install(TARGETS ${BINARY_NAME} LIBRARY DESTINATION ${LIBDIR} COMPONENT ${BINARY_NAME}-dev NAMELINK_ONLY) endif() if(UNIX AND NOT APPLE AND NOT HAIKU) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-16.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/16x16/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-24.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/24x24/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-32.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-48.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/48x48/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-64.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-96.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/96x96/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-128.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-256.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-512.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/512x512/apps RENAME mgba.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-16.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/16x16/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-24.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/24x24/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-32.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-48.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/48x48/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-64.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-96.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/96x96/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-128.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-256.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/mgba-512.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/512x512/apps RENAME io.mgba.${PROJECT_NAME}.png COMPONENT ${BINARY_NAME}) endif() else() set(BUILD_SHARED OFF) diff --git a/res/mgba-qt.desktop b/res/mgba-qt.desktop index 8f87bb40d..d5d98ab37 100644 --- a/res/mgba-qt.desktop +++ b/res/mgba-qt.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Version=1.0 -Icon=mgba +Icon=io.mgba.mGBA Exec=mgba-qt %f Terminal=false Type=Application diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 0aee0c636..3db5ebc55 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -424,7 +424,7 @@ install(TARGETS ${BINARY_NAME}-qt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-qt BUNDLE DESTINATION ${APPDIR} COMPONENT ${BINARY_NAME}-qt) if(UNIX AND NOT APPLE) - install(FILES ${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications COMPONENT ${BINARY_NAME}-qt) + install(FILES ${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications RENAME io.mgba.${PROJECT_NAME}.desktop COMPONENT ${BINARY_NAME}-qt) endif() if(UNIX AND NOT (APPLE AND DISTBUILD)) install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba-qt.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-qt)