Jump to content
IGNORED

Detecting the video system


pfeuh

Recommended Posts

Hello,

 

I use 2 real Atari with PAL video system. As I use sometimes Altirra to test my code, I have noticed the big difference with NTSC vidéo system. For the action, I can't do anything, european players will play not so fast :), but for the music, in NTSC, it remind me some Benny Hill music... Is there a software way to know if there is a PAL or NTSC video embedded?

 

Regards,

 

Pfeuh

Edited by pfeuh
Link to comment
Share on other sites

The PAL register on GTIA, location $D014. Value reads 1 for PAL, $F for NTSC.

 

Not 100% surefire since some people run Antic from the other system and Antic decides the framerate.

To cover that minute percentage of exceptions as well, the method of detection in assembler is to check the VCOUNT register in Antic, for NTSC it should never exceed value 131 decimal.

 

To have constant music speed, I just maintain a countdown that starts/resets at 5. When it hits 0, skip playback for that frame in NTSC.

  • Like 2
Link to comment
Share on other sites

To have constant music speed, I just maintain a countdown that starts/resets at 5. When it hits 0, skip playback for that frame in NTSC.

Sorry, I did not understand this part (as a non native speaker). I manage the tempo with the number of ticks for each semiquaver, it is in the range 5 - 15. It is this number of ticks that i would like to decrease in case of a NTSC system.

Link to comment
Share on other sites

When composing the music, do so assuming PAL system.

 

Then playback in NTSC, typically it's called once per frame. To keep to PAL speed you just skip the playback call every 6th frame.

It should be practically undetectable that you're doing this, I've done it with plenty of game/demo situations.

  • Like 1
Link to comment
Share on other sites

Not 100% surefire since some people run Antic from the other system and Antic decides the framerate.

To cover that minute percentage of exceptions as well, the method of detection in assembler is to check the VCOUNT register in Antic, for NTSC it should never exceed value 131 decimal.

 

As a member of "that minute percentage of exceptions", I wish more programmers would take that route. My machine detects as an NTSC, but plays as a PAL. When certain games (Pac-Man Arcade and Yoomp!, for two examples) adjust for they think is the correct speed, the results are off and way too slow.

 

Nothing against either game (or their programmers), I enjoy them both immensely on my unmolested machines. I just would like it if they ran properly on my 800, as this is my main system.

Link to comment
Share on other sites

>the method of detection in assembler is to check the VCOUNT register in Antic, for NTSC it should never exceed value 131 decimal.

 

I would try to implement this way, but I don't understand. Whatever the video system, graphic 0 for instance has 3 * 8 blank lines + 24 * 8 lines = 216 lines. How can NTSC have less than 216 lines?

 

 


 

Edited by pfeuh
Link to comment
Share on other sites

http://www.virtualdub.org/downloads/Altirra%20Hardware%20Reference%20Manual.pdf

 

VCOUNT allows the vertical position counter to be read to two-line resolution (that means, the value is incremented every other scan line) .

For NTSC, VCOUNT runs from 0 to 131; for PAL, it runs from 0 to 156.

  • Like 1
Link to comment
Share on other sites

I get the same value for PAL or NTSC... $7B. For sure VCOUNT grows during the VBI too, I smell something like that. When I uncomment the line which disables the VBI, the program crashes.


    PALREG      = $D014 ; a PAL video should give a 1
    RTCLOK_LOW  = $14
    VCOUNT      = $D40B
    WSYNC       = $D40A
    NMIEN       = $D40E

    NMIEN_DLI_BIT_VALUE = $80
    NMIEN_VBI_BIT_VALUE = $40

    * = $2000
    JMP     START

VCOUNT_MAX
    .BYTE 0

HEXTAB .BYTE $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $21, $22, $23, $24, $25, $26

    .MACRO SHOW_ACC
    PHA
    AND     #$f0
    LSR     A
    LSR     A
    LSR     A
    LSR     A
    TAY
    LDA     HEXTAB,Y
    STA     %1
    PLA
    AND     #$0f
    TAY
    LDA     HEXTAB,Y
    STA     %1+1
    .ENDM

START
    ;display GTIA PAL register
    LDA     PALREG
    SHOW_ACC 40040
    
    ; VBI disabled
    ; LDA     #0
    ; STA     NMIEN

    LDY     RTCLOK_LOW
LOOP
    CPY     RTCLOK_LOW
    BEQ     LOOP

    ;memorize higher VCOUNT during 4-5 seconds
LOOP_2
    INC     40003
    ;wait until next line
    STA     WSYNC
    ;compare line number to the biggest memorized one
    LDA     VCOUNT
    CMP     VCOUNT_MAX
    BMI     NEXT_LINE
    ;it's bigger, let's memorize
    STA     VCOUNT_MAX
NEXT_LINE
    CPY     RTCLOK_LOW
    BNE     LOOP_2

    ;restore VBI
    ; LDA     #NMIEN_VBI_BIT_VALUE
    ; STA     NMIEN
    
    ;display biggest line number
    LDA     VCOUNT_MAX
    SHOW_ACC 40080

LOOP_3
    INC     40004
    JMP     LOOP_3

Link to comment
Share on other sites

Thanks! Now I get $82 for NTSC and $9b for PAL :thumbsup: Assuming that I haven't stop the VBI.

 

Reading http://www.6502.org/tutorials/6502opcodes.html#BPL I suppose that BPL and BMI work with the 8th bit of ACC. That is what is marvellous in live: Every days, I learn! :)

 

 

 

This won't work:

    LDA     VCOUNT
    CMP     VCOUNT_MAX
    BMI     NEXT_LINE

Try:

    LDA     VCOUNT
    CMP     VCOUNT_MAX
    BCC     NEXT_LINE
Link to comment
Share on other sites

Thank you everybody, It's fixed now. I use this code:

    RTCLOK_LOW  = $14
    WSYNC       = $D40A
    VCOUNT      = $D40B

    NTSC_MAX_LINES = $83

SET_NTSC_FLAG
    LDA     #0
    STA     NTSC_FLAG
    STA     VCOUNT_MAX
    LDA     RTCLOK_LOW
    ADC     #5 ; add 5 or 6
    TAY
    ;let's loop...
SET_NTSC_FLAG_LOOP
    STA     WSYNC
    ;compare line number to the biggest memorized one
    LDA     VCOUNT
    CMP     VCOUNT_MAX
    BCC     SET_NTSC_FLAG_TEST
    ;it's bigger, let's memorize
    STA     VCOUNT_MAX
SET_NTSC_FLAG_TEST
    CPY     RTCLOK_LOW
    BNE     SET_NTSC_FLAG_LOOP
    ;let's examine result
    LDA     VCOUNT_MAX
    CMP     #NTSC_MAX_LINES
    BCS     SET_NTSC_FLAG_END
    
    LDA     #1
    STA     NTSC_FLAG

SET_NTSC_FLAG_END
    RTS
VCOUNT_MAX
    * = * +1
NTSC_FLAG
    * = * +1

About tempi, I used a pair of tables. Sorry Rybags, I hear the "glitch", that's why I've choosed this way. Tempi are not exactly the sames for NTSC and PAL, But the flow is regular.

PAL_VBI_PER_NOTE_TAB .BYTE   $09, $07, $06
NTSC_VBI_PER_NOTE_TAB .BYTE  $0b, $09, $07

INIT_TUNE
    ;ACC contains the tune number
    TAY
    
    CPY     CURRENT_TUNE
    BEQ     INIT_TUNE_END
    ;the tune is not the running one, let's continue to initialize
    STY     CURRENT_TUNE
    
    ... / ...

    LDA     NTSC_FLAG
    BNE     INIT_TUNE_NTSC
    LDA     PAL_VBI_PER_NOTE_TAB,Y
    BNE     INIT_TUNE_TEMPO
INIT_TUNE_NTSC
    LDA     NTSC_VBI_PER_NOTE_TAB,Y
INIT_TUNE_TEMPO
    STA     VBI_PER_NOTE

    ... / ...

Feel free to check it, in PAL or NTSC

 

Regards,

 

Pfeuh

CHOPPE_IMAGE.zip

Edited by pfeuh
  • Like 2
Link to comment
Share on other sites

Be careful with comparing to determine the system.

 

The actual VCOUNT value can be higher than listed for 1 machine cycle until Antic resets it back to zero.

 

What I'd suggest - use SEI at the start, to disable Stage 2 VBlank. That leaves RTCLOCK still updating but ensures the VBlank should be short enough that your code can still see when VCOUNT crosses over from maximum to 0.

 

Find the max value - then just compare with #135 (dec) - Carry Set = PAL, clear = NTSC.

  • Like 3
Link to comment
Share on other sites

What I'd suggest - use SEI at the start, to disable Stage 2 VBlank. That leaves RTCLOCK still updating but ensures the VBlank should be short enough that your code can still see when VCOUNT crosses over from maximum to 0.

Nice. How about the following implementation: wait for VCOUNT=130, then continuously poll VCOUNT and report PAL if VCOUNT reaches 132 or NTSC if VCOUNT goes back to 0. This seems to work in my tests:

 

    ; Carry set = PAL
    ; Carry clear = NTSC
detect_pal_or_ntsc
    sei
    lda #130
detect_wait_130
    cmp VCOUNT
    bne detect_wait_130
    clc
detect_loop
    lda VCOUNT
    beq detect_done
    cmp #132
    bcc detect_loop
detect_done
    rts

Can it be reduced any further?

  • Like 2
Link to comment
Share on other sites

That's probably close to the simplest way of doing it.
Further reduction might be had using extra registers - but the beauty is that the C bit has the result so the caller can do whatever needed from there, like:

 

bcc NTSC

 

or

 

LDA #0

ADC #0

TAY

 

gives a flag/index with NTSC=0 PAL=1 in Y.

  • Like 3
Link to comment
Share on other sites

Thanks guys, nice codes. As I'm not so aware about 6502 assembler, it's a pleasure to read such tips.

 

That's probably close to the simplest way of doing it.
Further reduction might be had using extra registers - but the beauty is that the C bit has the result so the caller can do whatever needed from there, like:

 

a flag/index with NTSC=0 PAL=1 in Y.

 

OK... but my function has to be renamed in SET_PAL_FLAG :) I've just implemented color sets for the different levels. As there is a visible difference between PAL and NTSC colors, I ask myself if I have to use this PAL flag to select a color set... But it is probably too much for just a homebrew game, and I am absolutely not an infographist.

Edited by pfeuh
Link to comment
Share on other sites

The difference between Pal/NTSC colours isn't near as bad as the 2600 but there are 2 important things to note.

 

Colour 4 on PAL is not red, it's more towards violet/purple. Star Raiders is a classic example of wrong colour selection.

Colour 10 on PAL is definately green, maybe with a hint of blue.

 

Colours 1 and 15 are very similar on PAL, on NTSC there's more of a difference.

  • Like 1
Link to comment
Share on other sites

It works for me in emulators (Altirra & Atari800Win), not tested on real HW. It just reads vcount and BIT it with next vcount value. If the next vcount value is zero, then it ends and A holds the last, topmost vcount value in a frame.

Edited by MaPa
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...