mirror of https://github.com/xemu-project/xemu.git
mac_via: extend timer calibration hack to work with A/UX
The A/UX timer calibration loop runs continuously until 2 consecutive iterations differ by at least 0x492 timer ticks. Modern hosts execute the timer calibration loop so fast that this situation never occurs causing a hang on boot. Use a similar method to Shoebill which is to randomly add 0x500 to the T2 counter value during calibration to enable it to eventually succeed. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-ID: <20231004083806.757242-21-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
9d35c6ade5
commit
b4d3a83b89
|
@ -983,6 +983,44 @@ static void via1_timer_calibration_hack(MOS6522Q800VIA1State *v1s, int addr,
|
|||
/* Looks like there has been a reset? */
|
||||
v1s->timer_hack_state = 1;
|
||||
}
|
||||
|
||||
if (addr == VIA_REG_T2CL && val == 0xf0) {
|
||||
/* VIA_REG_T2CL: low byte of counter (A/UX) */
|
||||
v1s->timer_hack_state = 5;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (addr == VIA_REG_T2CH && val == 0x3c) {
|
||||
/*
|
||||
* VIA_REG_T2CH: high byte of counter (A/UX). We are now extremely
|
||||
* likely to be in the A/UX timer calibration routine, so move to
|
||||
* the next state where we enable the calibration hack.
|
||||
*/
|
||||
v1s->timer_hack_state = 6;
|
||||
} else if ((addr == VIA_REG_IER && val == 0x20) ||
|
||||
addr == VIA_REG_T2CH) {
|
||||
/* We're doing something else with the timer, not calibration */
|
||||
v1s->timer_hack_state = 0;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if ((addr == VIA_REG_IER && val == 0x20) || addr == VIA_REG_T2CH) {
|
||||
/* End of A/UX timer calibration routine, or another write */
|
||||
v1s->timer_hack_state = 7;
|
||||
} else {
|
||||
v1s->timer_hack_state = 0;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* This is the normal post-calibration timer state once both the
|
||||
* MacOS toolbox and A/UX have been calibrated, until we see a write
|
||||
* to VIA_REG_PCR to suggest a reset
|
||||
*/
|
||||
if (addr == VIA_REG_PCR && val == 0x22) {
|
||||
/* Looks like there has been a reset? */
|
||||
v1s->timer_hack_state = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -998,6 +1036,7 @@ static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
|
|||
MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
|
||||
MOS6522State *ms = MOS6522(s);
|
||||
uint64_t ret;
|
||||
int64_t now;
|
||||
|
||||
addr = (addr >> 9) & 0xf;
|
||||
ret = mos6522_read(ms, addr, size);
|
||||
|
@ -1007,6 +1046,23 @@ static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
|
|||
/* Quadra 800 Id */
|
||||
ret = (ret & ~VIA1A_CPUID_MASK) | VIA1A_CPUID_Q800;
|
||||
break;
|
||||
case VIA_REG_T2CH:
|
||||
if (s->timer_hack_state == 6) {
|
||||
/*
|
||||
* The A/UX timer calibration loop runs continuously until 2
|
||||
* consecutive iterations differ by at least 0x492 timer ticks.
|
||||
* Modern hosts execute the timer calibration loop so fast that
|
||||
* this situation never occurs causing a hang on boot. Use a
|
||||
* similar method to Shoebill which is to randomly add 0x500 to
|
||||
* the T2 counter value during calibration to enable it to
|
||||
* eventually succeed.
|
||||
*/
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
if (now & 1) {
|
||||
ret += 0x5;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue