Introduce a new next_rtc_cmd_is_write() function to determine if an rtc command is a read or write, and start by using it to avoid shifting the rtc input value if a rtc read command is executed.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> --- hw/m68k/next-cube.c | 138 ++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 64 deletions(-) diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c index bb375b63ca..4aed80c9fe 100644 --- a/hw/m68k/next-cube.c +++ b/hw/m68k/next-cube.c @@ -165,6 +165,12 @@ static void next_scr2_led_update(NeXTPC *s) } } +static bool next_rtc_cmd_is_write(uint8_t cmd) +{ + return (cmd >= 0x80 && cmd <= 0x9f) || + (cmd == 0xb1); +} + static void next_scr2_rtc_update(NeXTPC *s) { uint8_t old_scr2, scr2_2; @@ -186,76 +192,80 @@ static void next_scr2_rtc_update(NeXTPC *s) ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } if (rtc->phase >= 8 && rtc->phase < 16) { - rtc->value = (rtc->value << 1) | - ((scr2_2 & SCR2_RTDATA) ? 1 : 0); - - /* if we read RAM register, output RT_DATA bit */ - if (rtc->command <= 0x1F) { - scr2_2 = scr2_2 & (~SCR2_RTDATA); - if (rtc->ram[rtc->command] & (0x80 >> (rtc->phase - 8))) { - scr2_2 |= SCR2_RTDATA; - } - - rtc->retval = (rtc->retval << 1) | - ((scr2_2 & SCR2_RTDATA) ? 1 : 0); - } - /* read the status 0x30 */ - if (rtc->command == 0x30) { - scr2_2 = scr2_2 & (~SCR2_RTDATA); - /* for now status = 0x98 (new rtc + FTU) */ - if (rtc->status & (0x80 >> (rtc->phase - 8))) { - scr2_2 |= SCR2_RTDATA; + if (next_rtc_cmd_is_write(rtc->command)) { + /* Shift in value to write */ + rtc->value = (rtc->value << 1) | + ((scr2_2 & SCR2_RTDATA) ? 1 : 0); + } else { + /* Shift out value to read */ + + /* if we read RAM register, output RT_DATA bit */ + if (rtc->command <= 0x1F) { + scr2_2 = scr2_2 & (~SCR2_RTDATA); + if (rtc->ram[rtc->command] & + (0x80 >> (rtc->phase - 8))) { + scr2_2 |= SCR2_RTDATA; + } + + rtc->retval = (rtc->retval << 1) | + ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } - - rtc->retval = (rtc->retval << 1) | - ((scr2_2 & SCR2_RTDATA) ? 1 : 0); - } - /* read the status 0x31 */ - if (rtc->command == 0x31) { - scr2_2 = scr2_2 & (~SCR2_RTDATA); - if (rtc->control & (0x80 >> (rtc->phase - 8))) { - scr2_2 |= SCR2_RTDATA; + /* read the status 0x30 */ + if (rtc->command == 0x30) { + scr2_2 = scr2_2 & (~SCR2_RTDATA); + /* for now status = 0x98 (new rtc + FTU) */ + if (rtc->status & (0x80 >> (rtc->phase - 8))) { + scr2_2 |= SCR2_RTDATA; + } + + rtc->retval = (rtc->retval << 1) | + ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } - rtc->retval = (rtc->retval << 1) | - ((scr2_2 & SCR2_RTDATA) ? 1 : 0); - } - - if ((rtc->command >= 0x20) && (rtc->command <= 0x2F)) { - scr2_2 = scr2_2 & (~SCR2_RTDATA); - /* for now 0x00 */ - time_t time_h = time(NULL); - struct tm *info = localtime(&time_h); - int ret = 0; - - switch (rtc->command) { - case 0x20: - ret = SCR2_TOBCD(info->tm_sec); - break; - case 0x21: - ret = SCR2_TOBCD(info->tm_min); - break; - case 0x22: - ret = SCR2_TOBCD(info->tm_hour); - break; - case 0x24: - ret = SCR2_TOBCD(info->tm_mday); - break; - case 0x25: - ret = SCR2_TOBCD((info->tm_mon + 1)); - break; - case 0x26: - ret = SCR2_TOBCD((info->tm_year - 100)); - break; - + /* read the status 0x31 */ + if (rtc->command == 0x31) { + scr2_2 = scr2_2 & (~SCR2_RTDATA); + if (rtc->control & (0x80 >> (rtc->phase - 8))) { + scr2_2 |= SCR2_RTDATA; + } + rtc->retval = (rtc->retval << 1) | + ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } - if (ret & (0x80 >> (rtc->phase - 8))) { - scr2_2 |= SCR2_RTDATA; + if ((rtc->command >= 0x20) && (rtc->command <= 0x2F)) { + scr2_2 = scr2_2 & (~SCR2_RTDATA); + /* for now 0x00 */ + time_t time_h = time(NULL); + struct tm *info = localtime(&time_h); + int ret = 0; + + switch (rtc->command) { + case 0x20: + ret = SCR2_TOBCD(info->tm_sec); + break; + case 0x21: + ret = SCR2_TOBCD(info->tm_min); + break; + case 0x22: + ret = SCR2_TOBCD(info->tm_hour); + break; + case 0x24: + ret = SCR2_TOBCD(info->tm_mday); + break; + case 0x25: + ret = SCR2_TOBCD((info->tm_mon + 1)); + break; + case 0x26: + ret = SCR2_TOBCD((info->tm_year - 100)); + break; + } + + if (ret & (0x80 >> (rtc->phase - 8))) { + scr2_2 |= SCR2_RTDATA; + } + rtc->retval = (rtc->retval << 1) | + ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } - rtc->retval = (rtc->retval << 1) | - ((scr2_2 & SCR2_RTDATA) ? 1 : 0); } - } rtc->phase++; -- 2.39.5