Menu

#559 PSG/Z80 timing combination shows something is off

Next_release
closed-fixed
timing (1)
5
2014-12-23
2014-12-09
No

Grauw wrote:

"I know just the other day I did a experiment (rom attached) with PSG generating a pulse wave with duty cycle. In that experiment the MSX has to output volume changes in sync with the PSG, and the timing only worked correctly when I assumed 12 cycles for out instructions (tested on Yamaha CX5MII). Just a single cycle offset and it starts modulating audibly.

Though, running it on openMSX, there is some slight modulation present, so it seems that openMSX is off by a fraction of a cycle. Note that even if I deduct or add a cycle, it never becomes stable. Could be a little openMSX bug in PSG timing, or Z80 timing."

1 Attachments

Discussion

  • Laurens Holst

    Laurens Holst - 2014-12-09

    Counting the number of samples in the "record_channels PSG 1" dump, the period is set to exactly 256 so every wave should be 512 samples long... and for a few individual waves I looked at it this seemed to be correct, but looking at it over longer ranges it is not the case.

    So it looks like the PSG is out of sync, not the Z80.

    Source code paste + description will follow in a sec.

     
  • Laurens Holst

    Laurens Holst - 2014-12-09
    ;
    ; Top-level PSGDuty program class
    ;
    PSG_REGISTER_SELECT: equ 0A0H
    PSG_WRITE: equ 0A1H
    PSG_READ: equ 0A2H
    
    PSG_PERIOD_GENERATOR_CONTROL: equ 0
    PSG_NOISE_GENERATOR_CONTROL: equ 6
    PSG_MIXER_CONTROL: equ 7
    PSG_AMPLITUDE_CONTROL: equ 8
    PSG_ENVELOPE_PERIOD_CONTROL: equ 11
    PSG_ENVELOPE_SHAPE_CONTROL: equ 13
    
    PSGDuty_PERIOD: equ 100H
    PSGDuty_PERIOD_CYCLES: equ PSGDuty_PERIOD * 16 ; 4096
    
        org 4000H
    
        db "AB"
        dw Main
        dw 0, 0, 0, 0, 0, 0
    
    ;
    ; Program entry point
    ;
    Main:
        di
    
        ld a,PSG_PERIOD_GENERATOR_CONTROL
        out (PSG_REGISTER_SELECT),a
        ld a,PSGDuty_PERIOD
        out (PSG_WRITE),a
    
        ld a,PSG_PERIOD_GENERATOR_CONTROL + 1
        out (PSG_REGISTER_SELECT),a
        ld a,PSGDuty_PERIOD >> 8
        out (PSG_WRITE),a
    
        ld a,PSG_AMPLITUDE_CONTROL
        out (PSG_REGISTER_SELECT),a
        ld a,13
        out (PSG_WRITE),a
    
        ld b,10   ; offset
        djnz $
    
    Loop:
        ld bc,(PSGDuty_PERIOD_CYCLES - 42) / 28  ; 11
    WaitLoop:
        dec bc            ; 7
        ld a,b            ; 5
        or c              ; 5
        jp nz,WaitLoop    ; 11
    
        jp $+3            ; 11
        jp $+3            ; 11
    
        ld a,0            ; 8
        out (PSG_WRITE),a ; 12
        jp Loop2          ; 11
    
    Loop2:
        ld bc,(PSGDuty_PERIOD_CYCLES - 42) / 28  ; 11
    WaitLoop2:
        dec bc            ; 7
        ld a,b            ; 5
        or c              ; 5
        jp nz,WaitLoop2   ; 11
    
        jp $+3            ; 11
        jp $+3            ; 11
    
        ld a,13           ; 8
        out (PSG_WRITE),a ; 12
        jp Loop           ; 11
    
    ;
    ; pad
    ;
        ds 6000H - $
    
     
  • Laurens Holst

    Laurens Holst - 2014-12-09

    In this program I tried out the "SID effect", PSG waves with non-square duty cycle, as it’s used in many Atari ST trackers (though there it’s interrupt-driven).

    It plays a square wave with the PSG, and then use the CPU to toggle the volume on and off at exactly the same rate with cycle-accurate timing, cutting off part of the wave.

     
  • Manuel Bilderbeek

    I can't reproduce this anymore with the latest git HEAD. Can you confirm, grauw?

     
  • Laurens Holst

    Laurens Holst - 2014-12-23
    • status: open --> closed-fixed
     
  • Laurens Holst

    Laurens Holst - 2014-12-23

    Fixed by ba9fcc4, props!

     
  • Manuel Bilderbeek

    • assigned_to: Wouter Vermaelen
     
  • Manuel Bilderbeek

    Indeed, thanks Wouter!

     
MongoDB Logo MongoDB