leomil72 / LM80C

A Z80-based homebrew computer withTMS9918, AY-3-8910, Z80 CTC, Z80 PIO, and Z80 SIO
GNU General Public License v3.0
100 stars 17 forks source link

sound generator occasionally not turned off in BRISCOLA #23

Closed nippur72 closed 4 years ago

nippur72 commented 4 years ago

When playing biscola.bas, occasionally the sound generator is not turned off (in the emulator you can hear an high-pitched continuous tone that you won't hear on the real machine). The issue manifests once in two or three complete briscola matches.

As the issue occurs and the game goes on, I still can hear the "card shuffle" sound, but after it the voice is never turned off (which is very odd).

I stopped the program and dumped the state of the sound chip, you can see bit 0 of reg7 is 0 instead of 1: image

Does this gives you a clue?

leomil72 commented 4 years ago

Is it related to the latest firmware releases, after the SOUND statement fixes, or was it already present before? I mean, could it be related to the latest changes in the SOUND management mods?

nippur72 commented 4 years ago

past firmware was buggy, the voices were always turned on, so I can't tell.

leomil72 commented 4 years ago

Wait a moment. Noise mixing is controlled by bits 3-5. Bits 0-2 set the normal analog channels. So if you get 190 means that you had the channel 1 on, and SOUND 4 doesn't alter such bit. There's something else earlier. For some reason you had the analog channel #1 on into the mixer. Did you play with SOUND before to execute the game? PS: I tried several times doing SOUND4,30:PAUSE1:SOUND4,0 and always get 191 from reg #7

nippur72 commented 4 years ago

No, I didn't have any sound running before, I'm just starting fresh with a new instance of the emulator.

I am also unable to replicate the issue by running SOUND4,30:PAUSE1:SOUND4,0 several times. It happens only in briscola.bas, I don't know why.

I've put a watchpoint at the address 0x2989 (sound routine below NOS3 label) printing the A register. Normally I get the values 183 and 191, but when the issue occurs get in sequence:

a=246
a=254
a=182
a=190
a=182
a=190
a=182
a=190
(last two values repeated for the rest of the game)

Could it be that the interrupt keyboard routine is interfering with the read of register 7? E.g. interrupt occurring just in between the selection of reg 7 and the actual IN A, (C). I'm guessing.

nippur72 commented 4 years ago

the debug code to paste in the JavaScript console is the following:

   debugBefore = ()=>  {
      let state = cpu.getState();
      if(state.pc == 0x2982 && (state.a != 191 && state.a !=183)) console.log(`a=${state.a}`);
   }
leomil72 commented 4 years ago

There could be a race condition between the interrupt service routine and the SOUND code. But this is strange since the keyboard routine happens with or without a program is running... Moreover, I don't understand it's happening only in that game. To be honest, I played Briscola several times on the real machine but never noticed this issue.

I could try to atomize the SOUND code in the part that reads & sets the PSG disabling interrupts before such point.

leomil72 commented 4 years ago

I played several games of Briscola and never experienced such issue. Unless more detailed info to replicate it on the real machine, I classify it as an emulator bug and, at the moment, close this issue.

nippur72 commented 4 years ago

I am now able to replicate it. If you run the following program, the value 183 will be printed once in a while.

10 volume 1,15
20 sound 4,10:sound 4,0
30 if sstat(7)<>191 then print sstat(7)
40 goto 20

I guess it's the keyboard interrupt routine, because if I decrease the $90 CTC constant (at 0x031c) the issue occurs more frequently.

leomil72 commented 4 years ago

I must apologize. You were right. When the firmware is executing the CH3 interrupt service routine, during the keyboard reading the code loads adn save the reg 7 (the mixer) for setting the keyboard lines for proper input/output states, in case the user had "played" with regs 14 & 15. If the interrupt service routine is called while the BASIC is executing the SOUND statement, this leads to unwanted behaviors since there is a real race condition between 2 points of the FW that are accessing the same PSG register. To solve it, I atomized the portions of code of the BASIC interpreter that could access the PSG registers (SOUND and SSTAT/SREG), and now I only get 191 when executing the test program above.