Timer immediately overflows when 0xff is loaded into it
Closed this issue · 5 comments
As soon as 0xff is loaded, overflow will be 1, and at the next cycle, flag will be 1, too.
Changing the flag setting condition fixes it (if it has to be fixed)
else if( cenop && zero && load && overflow) flag<=1'b1;
Also it makes the Adlib detection code in Wolf3d work:
https://github.com/id-Software/wolf3d/blob/05167784ef009d0d0daefe8d012b027f39dc8541/WOLFSRC/ID_SD.C#L1585
I think this bug also makes the timer to fire the irq one count earlier and correcting this will have an effect to the free-running counter, as in your comment:
// Free running counter, resetting
// the value of this part with the load
// event can slow down music, vg Bad Dudes
Plus: are you sure flagen only masks the IRQ, not 'load' (e.g. doesn't stop the timer?)
I did not try it yet, but doesn't this patch makes the timer run forever?
BTW, I got an idea from a different implementation some time ago:
if (~din[7]) begin
flagen_A <= ~din[6];
flagen_B <= ~din[5];
{ load_B, load_A } <= din[1:0];
end
E.g. bit 7 masks the update of REG_TIMER. It didn't make much difference with AdLib games, but maybe worth to try on arcades. Maybe Bad Dudes resets the IRQ frequently, and this should not stop the timers, as it does without the masking.
I tried your patch, and it makes Adlib detection unreliable (the check code expects the timer is not triggering IRQ until its explicitly started).
E.g. after this sequence:
alOut(4,0x60); // Reset T1 & T2
alOut(4,0x80); // Reset IRQ
status1 = readstat();
status1 must read 0 for both timer flags.
No more issues encountered!