jotego / jtopl

Verilog module compatible with Yamaha OPL chips
GNU General Public License v3.0
46 stars 9 forks source link

Timer immediately overflows when 0xff is loaded into it #4

Closed gyurco closed 2 years ago

gyurco commented 2 years ago

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?)

jotego commented 2 years ago

Could you (@gyurco ) check if this new commit dfaa563 works ok with Wolf3d? I had to add that line to restore the music speed in Bad Dudes vs Dragon Ninja

gyurco commented 2 years ago

I did not try it yet, but doesn't this patch makes the timer run forever?

gyurco commented 2 years ago

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.

gyurco commented 2 years ago

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.

gyurco commented 2 years ago

No more issues encountered!