Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user maak ! (Registered 2024-04-18) You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > detecting pal, drean, ntsc or old ntsc
2012-11-26 14:21
Peiselulli

Registered: Oct 2006
Posts: 81
detecting pal, drean, ntsc or old ntsc

Hello,
I want to know if a test like this is reliable for the four different machine types PAL, NTSC, NTSC(old) and DREAN (ACME source code):

OLD_NTSC = 1
NTSC = 0
PAL = 2
DREAN = 3

        !to "detect.prg",cbm
	!cpu 6510

	* = $0801
	!by $0b,$08,$00,$00,$9e,$32,$30,$36,$31,$00,$00,$00
		
detect:	sei
w0:  	lda $d012
w1:  	cmp $d012
	beq w1
	bmi w0
	and #$03
	cmp #$01
	bne w2
	lda #OLD_NTSC
	bne detected ; unconditional
w2:	cmp #$03
	lda #$00
	rol
	beq detected	;ntsc

	;check for drean or pal
	ldx #$00
	lda #$10
l	inx
	cmp $d012
	bne l
	lda #PAL
	cpx #$70
	bcc detected
	;is a drean
	lda #DREAN
detected:
	tay
	lax offset,y
l2:	lda base_text,x
	beq end
	jsr $ffd2
	inx
	bne l2
end:	lda #$0d
	jmp $ffd2

base_text:
old_ntsc_text:	!text "OLD "
ntsc_text:	!text "NTSC",0
pal_text:	!text "PAL",0
drean_text:	!text "DREAN",0

offset:		
	!byte ntsc_text-base_text
	!byte old_ntsc_text-base_text
	!byte pal_text-base_text
	!byte drean_text-base_text


2012-11-26 18:55
Devia

Registered: Oct 2004
Posts: 401
How many lines does the Drean have?
And is the Drean 6572 or 6573?

2012-11-26 20:13
tlr

Registered: Sep 2003
Posts: 1702
Nice detection code!

@devia: 312 lines.
2012-11-26 20:15
Moloch

Registered: Jan 2002
Posts: 2891
Nice detection routine, will have to give it some testing.

Quoting Devia
How many lines does the Drean have?
And is the Drean 6572 or 6573?

6572

Lots of details here
http://www.solidstate.com.ar/2011/06/flashback-vic-ii-timings/
2012-11-26 22:26
Flavioweb

Registered: Nov 2011
Posts: 442
Works perfectly using Vice 2.4.

Chapeau.
2012-11-26 22:31
Peiselulli

Registered: Oct 2006
Posts: 81
Ok, it can made be shorter. Instead of
	lda #PAL
	cpx #$70
	bcc detected
	;is a drean
	lda #DREAN
detected:

it can be changed to:
	lda #PAL/2
	cpx #$70
	rol
detected:

but this is not the point here.
Can somebody check it on a real Drean C64 ?
2012-11-26 23:51
hedning

Registered: Mar 2009
Posts: 4584
I could try to, tomorrow. Oh. It is already tomorrow. Later today that is, then. :)
2012-11-27 11:27
Flavioweb

Registered: Nov 2011
Posts: 442
You inspired me to write my version:
SCAN_START
   LDA $D012
LINE_CMP
   CMP $D012
   BEQ LINE_CMP
   BMI SCAN_START
   AND  #%00001111
   CLC
   LSR
   BCS IS_NTSC
   LSR
   BCS IS_OLDNTSC
;check for drean or pal
   LDX #$00
   LDA #$10
L
   INX
   CMP $D012
   BNE L
   CPX #$70
   BCC IS_PAL
IS_DREAN
    RTS
IS_NTSC
    RTS
IS_OLDNTSC
    RTS
IS_PAL
    RTS

Is from the top of my mind... so isn't tested.
Hope it works.
2012-11-27 12:30
Frantic

Registered: Mar 2003
Posts: 1627
Once this code is tested and tried I would like to encourage people to add some of this to the corresponding page on codebase 64:

http://codebase64.org/doku.php?id=base:detect_pal_ntsc
2012-11-27 20:18
Flavioweb

Registered: Nov 2011
Posts: 442
This version works in Vice:
;------------------------------------------------------------------------------- 
; Vic mode detection.
; Detect Pal, Ntsc, Old Ntsc, Drean
; Based on source posted by Peiselulli
; [url=http://noname.c64.org/csdb/forums/?roomid=11&topicid=94459]
; Tass version
; (C) 2012 by FlavioWeb/Hokuto Force
;------------------------------------------------------------------------------- 
    .CPU 6502
    *= $0801
;---------------------------------------
    .BYTE $0b, $08, $00, $00, $9e, $32, $30, $36
    .BYTE $31, $00, $00, $00
;---------------------------------------
    SEI
SCAN_START
    LDA $D012
LINE_CMP
    CMP $D012
    BEQ LINE_CMP
    BMI SCAN_START
    ADC #$00
    LSR
    BCS IS_NTSC
    LSR
    BCS IS_OLDNTSC
    LDX #$00                            ; Check for drean or pal
    LDA #$10
L
    INX
    CMP $D012
    BNE L
    CPX #$70
    BCC IS_PAL
IS_DREAN
    LDX #DREAN_TEXT-OLD_NTSC_TEXT
    BNE DETECTED
IS_NTSC
    LDX #NTSC_TEXT-OLD_NTSC_TEXT
    BNE DETECTED
IS_OLDNTSC
    LDX #$00
    BEQ DETECTED
IS_PAL
    LDX #PAL_TEXT-OLD_NTSC_TEXT
DETECTED
    LDA OLD_NTSC_TEXT,X
    BEQ END
    JSR $FFD2
    INX
    BNE DETECTED
END
    CLI
    RTS
;---------------------------------------
OLD_NTSC_TEXT
    .TEXT "OLD "
NTSC_TEXT
    .TEXT "NTSC"
    .BYTE $00
PAL_TEXT
    .TEXT "PAL"
    .BYTE $00
DREAN_TEXT
    .TEXT "DREAN"
    .BYTE $00
2014-01-19 11:41
Norrland

Registered: Aug 2011
Posts: 14
Hi there!
I'll hijack this tread since I have some reported issues with the pal/ntsc-check in That Demo with the New Hubbard Tune. In this one, I ran out of (spare)time to do a proper ntsc-compatible routine for showing a flipicture with sprites/unrolled code so I added a message/program stop if the machine seemed like a non-pal (didn't care about drean).

Anyway, some people reported that they got the error message despite using pal (at least in vice, not sure if anyone encountered it on real hardware). I haven't seen it on real hardware or vice myself.

my code:
	;ntsctest
	l1 
	lda $d012

	l2 
	cmp $d012
        beq l2
        bmi l1
        and #$03
	cmp #$03	;if #$03 pal, (or drean)
	beq $0900

	;else, show ntsc-message
	lda #$30
	sta $d018	;charset on $0000 ($8000) and screenram on $0800 ($8800)
        jmp *


I'm counting the rasterlines for the test (used this code before since I once read about the topic at codebase), and to me it's seems to be exactly the same codesnippet as the short test on codebase:

Quote:

The easiest way to determine cycles/rasterline is to count the rasterlines:

312 rasterlines -> 63 cycles per line [PAL: 6569 VIC]
263 rasterlines -> 65 cycles per line [NTSC: 6567R8 VIC]
262 rasterlines -> 64 cycles per line [NTSC: 6567R56A VIC]

w0 LDA $D012
w1 CMP $D012
BEQ w1
BMI w0
AND #$03

Â…and the results in the akku:

#$03 -> 312 rasterlines
#$02 -> 263 rasterlines
#$01 -> 262 rasterlines


I thought that method to test was ok, can anyone help me finding why not (or is this just emulator-related?

Groepaz: you mentioned in the release that you encountered this problem on your pal-machine. Was that real hardware or emulator?
2014-01-19 12:35
Burglar

Registered: Dec 2004
Posts: 1031
I can understand why ppl want to know how to manually detect pal/ntsc, but for real releases, what's wrong with good old $02a6?

lda $02a6
beq ntsc
bne pal

its really that simple.

and with micro64 tdwtnht also detected ntsc while I was running pal. then restarted it and it was detected as pal... so, obviously ur check is seriously broken.

again, use $02a6, it's why it's there!
2014-01-19 13:02
tlr

Registered: Sep 2003
Posts: 1702
IIRC $02a6 is far from reliable.
2014-01-19 13:40
Flavioweb

Registered: Nov 2011
Posts: 442
You forgot a SEI.
If an irq is fired in the middle of the loop... all fucks.
2014-01-19 13:59
Ninja

Registered: Jan 2002
Posts: 404
Burglar: Two reasons given here: http://www.the-dreams.de/articles/pal-ntsc-detector.txt
2014-01-19 21:21
Fungus

Registered: Sep 2002
Posts: 609
This works :P

I made it fix jiffyclock timing so things would run at the same speed on different systems (basic etc). But it detects the different systems too reliably. If it bugs in an emulator then the emulator needs to be fixed.

;-----------------------------------------
;PAL/NTSC detector
;
;Fungus/Nostalgia
;
;2010
;-----------------------------------------

;ntsc/pal-n jiffy clock =
;pal-m jiffyclock = 16420/$4024 $4000 rounded for 60 times/sec
;pal-m jiffyclock = 19656/$4cc8 $4c00 rounded for 50 times/sec
;ntsc-m (old) jiffyclock = 16832/$41c0 $4100 rounded for 60 times/sec
;ntsc-m (old) jiffyclock = 20198/$4ee6 $4e00 rounded for 50 times/sec
;ntsc-m jiffyclock = 17095/$42c7 $4200 rounded for 60 times/sec
;ntsc-m jiffyclock = 20514/$5022 $5000 rounded for 50 times/sec
;pal-n jiffyclock = 16900/$4204 $4200 rounded for 60 times/sec
;pal-n jiffyclock = 20280/$4f38 $4f00 rounded for 50 times/sec
;
;pal-m cycles per line is 63
;ntsc-m old cycles per line is 64
;ntsc-m standard and pal-n cycles per line is 65


* = $1000

sei
lda #$00
sta $d012
lda #$01
sta $d01a
lda #$1b
sta $d011
lda #$1f
sta $dc0d
sta $dd0d
lda #<irq1
sta $0314
lda #>irq1
sta $0315
lda $dc0d
lda $dd0d
inc $d019
cli
loop jmp *

lda result
eor #$ff
sta result
lda result+$01
eor #$ff
sta result+$01
cmp #$41
beq ntscold
cmp #$42
beq ntscnew
cmp #$4c
beq pal
bcs drean
unknown jmp *

ntscold
lda #$80
sta $02a6
lda ntscoldjiffy
sta $dc05
bne done
ntscnew
lda #$00
sta $02a6
ntscnewdone
lda ntscjiffy
sta $dc05
bne done

pal
lda #$01
sta $02a6
paldone
lda paljiffy
sta $dc05
bne done

drean
lda #$81
sta $02a6
dreandone
lda dreanjiffy
sta $dc05
done
lda #$00
sta $dc04

sei ;use this to reset to normal after check
lda #$31
sta $0314
lda #$ea
sta $0315
lda #$81
sta $dc0d
lda $dc0e
and #$80
ora #$11
sta $dc0e
lda $dc0d
cli
rts
irq1
ldx #$10
dex
bpl *-1
lda #<irq2
sta $0314
lda #>irq2
sta $0315
lda #$ff
sta $dc04
sta $dc05
lda #$19
sta $dc0e
inc $d019
jmp $ea81
irq2
lda $dc05
sta result+$01
lda $dc04
sta result
lda #$00
sta $d01a
lda #$2c
sta loop
inc $d019
jmp $ea81

result
.byte $00,$00
paljiffy
.byte $40
ntscjiffy
.byte $42
ntscoldjiffy
.byte $41
dreanjiffy
.byte $42
2014-01-19 21:34
chatGPZ

Registered: Dec 2001
Posts: 11100
Quote:
Groepaz: you mentioned in the release that you encountered this problem on your pal-machine. Was that real hardware or emulator?

emu. however, even the most broken emulator has the right amount of cycles per line and frame. as others said already, your detection is broken :)
Quote:
what's wrong with good old $02a6?

the kernal is broken, thats why people started adding those checks to their releases back in 1990 you know :)
2014-01-21 04:30
TWW

Registered: Jul 2009
Posts: 541
I see a lot preferr to count raterlines. How about counting total amount of cycles between VSYNC?

Here is how I'd do it:


    sei              // Set Interrupt Flag (MPU Ignore IRQ line)
    cld              // No stupid tricks ;-)
    lda #$7f
    sta $dc0d        // No more IRQ Interrupts from CIA #1
    lda #$00
    sta $d01a        // No more IRQ Interrupts from VICII
    lda $dc0d        // Ack any latent CIA #1 Interrupts
    lda #$01
    sta $d019        // Ack any latent VICII Interrupts
    lda #$35
    sta $01          // Switch off the MPUs access to BASIC and KERNAL ROM and access the RAM instead (dec/inc $01 allows access to IO RAM).

    // Ignore NMIs
    lda #<nmivector
    sta $fffa
    lda #>nmivector
    sta $fffb        // Set NMI HW Vector to point to RTI
    jmp *+4
nmivector:
    rti
    lda #$00
    sta $dd0e  // Stop CIA #2 Timer A
    sta $dd04
    sta $dd05  // Set Timer A = 0 (NMI will trigger immediately when Timer A is restarted)
    lda #$81
    sta $dd0d  // Set Timer A as NMI source
    lda #$01
    sta $dd0e  // Start Timer A (triggers NMI and unless the NMI get's acked, any new NMI's will be ignored).

    // From this point on we will not be disturbed and can commence testing.

    lda #$00
    sta $d015  // No Sprites
    lda #$00
    sta $d011  // Turn off screen to avoid badlines


    // Detect the model
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // 312 rasterlines -> 63 cycles per line PAL        => 312 * 63 = 19656 Cycles / VSYNC  => #>76  %00
    // 262 rasterlines -> 64 cycles per line NTSC V1    => 262 * 64 = 16768 Cycles / VSYNC  => #>65  %01
    // 263 rasterlines -> 65 cycles per line NTSC V2    => 263 * 65 = 17095 Cycles / VSYNC  => #>66  %10
    // 312 rasterlines -> 65 cycles per line PAL DREAN  => 312 * 65 = 20280 Cycles / VSYNC  => #>79  %11

    // Use CIA #1 Timer A to count cycled in a frame
    lda #$ff
    sta $dc06
    sta $dc07  // Latch #$ffff to Timer B

    lda $d011
    bmi *-3
    lda $d012
    bne *-3    // VSYNC

    lda #%00011001
    sta $dc0f  // Start Timer B (One shot mode (Timer stops automatically when underflow))

    lda $d011
    bpl *-3    // Wait untill we cross the 256 rasterline

    lda $d011
    bmi *-3
    lda $d012
    bne *-3    // VSYNC again

    lda #$ff
    sec
    sbc $dc07  // Hibyte number of cycles used
    and #%00000011

    sta $0400

    // Turn back on screen to see result (#$00, #$01, #$02 or #$03)
    lda #$1b
    sta $d011

    jmp *



I got some funny result on the emulator when using inject into ram etc. on the first reading but it stabilizes quickly with a small jitter ofcourse. If you want perfection you could stab and use a raster to sync and subtract the overhead to get the exact cycle number but for this purpose this would be pointless as the hi-byte of the Timer is enough to tell the different models apart.
2014-01-21 11:44
JackAsser

Registered: Jun 2002
Posts: 1987
@TWW: Clean!
2014-01-21 13:36
Norrland

Registered: Aug 2011
Posts: 14
Thanks for all suggestions, and especially to Flavioweb... Of course I missed the sei... :) actually I have it as the first opcode after the test... :P
2014-01-21 19:33
tlr

Registered: Sep 2003
Posts: 1702
Quoting TWW
I see a lot preferr to count raterlines. How about counting total amount of cycles between VSYNC?

Here is how I'd do it:
...


Nicely done. I've used something similar. Though my approach was to measure the number of cycles per line, then the number of lines and "multiply". The result is cycles/frame-1 and cycles/line-1 for direct loading into timers.
2014-01-21 21:47
MagerValp

Registered: Dec 2001
Posts: 1055
TWW's cycle counter is impressive, but seems like overkill for most things :) I prefer a straightforward approach:

init:
	lda #$7f	; Disable kernal IRQ.
	sta $dc0d
	
	lda #$ff	; Start on line 255.
:	cmp $d012
	bne :-
	
@nextline:
	lda $d012	; Wait until the next line.
:	cmp $d012
	beq :-		; A contains the previous line number.
	
	bit $d011	; Are we back on line 0?
	bmi @nextline
	
	ora #$30	; A contains the LSB of the last line number:
	sta $0400	;   $05 = 262 x 64 cycle NTSC
	lda #1		;   $06 = 263 x 65 cycle NTSC
	sta $d800	;   $37 = 312 x 63 cycle PAL or 312 x 65 cycle DREAN
2014-01-22 04:42
Peiselulli

Registered: Oct 2006
Posts: 81
@MagerValp : But the main reason for starting this thread is missing : detection between "drean" an "pal".
2014-01-22 04:48
TWW

Registered: Jul 2009
Posts: 541
Slightly improved version:

    // Use CIA #1 Timer B to count cycled in a frame
    lda #$ff
    sta $dc06
    sta $dc07  // Latch #$ffff to Timer B

    bit $d011
    bpl *-3    // Wait untill Raster > 256
    bit $d011
    bmi *-3    // Wait untill Raster = 0

    ldx #%00011001
    stx $dc0f  // Start Timer B (One shot mode (Timer stops automatically when underflow))

    bit $d011
    bpl *-3    // Wait untill Raster > 256
    bit $d011
    bmi *-3    // Wait untill Raster = 0

    sec
    sbc $dc07  // Hibyte number of total cycles
    and #%00000011
2014-01-22 05:21
Flavioweb

Registered: Nov 2011
Posts: 442
Here it is the stabilized TWW version:
INIT
    SEI
    CLD
    LDX #$FF
    TXS
    LDA #$2F
    STA $00
    LDA #$35
    STA $01
;-------------------
    LDX #<NO_NMI
    LDY #>NO_NMI
    STX $0318
    STY $0319
    STX $FFFA
    STY $FFFB
    LDY #$00
    STY $DC03                           ; Port $DC01 = Input
    DEY
    STY $DC02                           ; Port $DC00 = Output
;-------------------
    LDA #$7F
    STA $DC0D
    STA $DD0D
    LDA $DC0D
    LDA $DD0D
;-------------------
    LDA #$00
    STA $DD0E                           ; Stop CIA #2 Timer A
    STA $DD04
    STA $DD05                           ; Set Timer A = 0 (NMI will trigger immediately when Timer A is restarted)
    LDA #$81
    STA $DD0D                           ; Set Timer A as NMI source
    LDA #$01
    STA $DD0E                           ; Start Timer A (triggers NMI and unless the NMI get's acked, any new NMI's will be ignored).
    LDA #$00                            ; From this point on we will not be disturbed and can commence testing.
    STA $D015                           ; No Sprites
;------------------------------------------------------------------------------
; Detect the model
;---------------------------------------
; 312 rasterlines -> 63 cycles per line PAL        => 312 * 63 = 19656 Cycles / VSYNC
; 262 rasterlines -> 64 cycles per line NTSC V1    => 262 * 64 = 16768 Cycles / VSYNC
; 263 rasterlines -> 65 cycles per line NTSC V2    => 263 * 65 = 17095 Cycles / VSYNC
; 312 rasterlines -> 65 cycles per line PAL DREAN  => 312 * 65 = 20280 Cycles / VSYNC
;------------------------------------------------------------------------------
    LDA #$FF                            ; Use CIA #1 Timer A to count cycled in a frame
    STA $DC06
    STA $DC07                           ; Latch #$ffff to Timer B
    LDY #%00011001
    LDA #$7F
WAIT_BEAM_01
    CMP $D012
    BNE WAIT_BEAM_01
    BIT $DEAD
    BIT $BEEF
    STA $D011
    STY $DC0F                           ; Start Timer B (One shot mode (Timer stops automatically when underflow)
    LDY #$00
    LDA #$1B
    STA $D011
    LDA #$7F
WAIT_BEAM_02
    CMP $D012
    BNE WAIT_BEAM_02
    BIT $DEAD
    BIT $BEEF
    STA $D011
;-------------------
    STY $DC0F
    LDX $DC06
    LDY $DC07
    STY $0400
    STX $0401
    LDA #$1B                            ; TURN BACK ON SCREEN TO SEE RESULT
    STA $D011
;-------------------
WAIT_SOME_SPACE
    LDA $DC01
    AND $DC00
    AND #$10
    BNE WAIT_SOME_SPACE
    JMP INIT
;-------------------
NO_NMI
    RTI

In $0400/$0401 there are values to subtract from $FFFF to obtain cycles/VSYNC (-1).
PAL: $B338 ($FFFF-$B338 = $4CC7)
NTSC: $BD39 ($FFFF-$BD39 = $42C6)
DREAN: $B0C8 ($FFFF-$B0C8 = $4F37)

Tested on "x64 2.4.5 r27742M".
Someone can test it on real hardware?
2014-01-22 09:12
Fungus

Registered: Sep 2002
Posts: 609
Mine counted cycles also and used vsync to check. Although I made a small math error about old ntsc. sprites and DMA don't matter with a timer, since the clock runs independant of such stuff, and the up to 1 line delay doesn't matter really.

Nice different ways of checking, cool to see. Not that anyone cares about NTSC ;)
2014-01-22 11:45
MagerValp

Registered: Dec 2001
Posts: 1055
Quoting Peiselulli
@MagerValp : But the main reason for starting this thread is missing : detection between "drean" an "pal".

Yes, but that was in 2012, H Macaroni's thread necrophilia was regarding PAL vs NTSC. For Drean vs PAL it's of course a little more work.

I'd love to see some Drean releases though, two extra cycles per line should allow for some neat tricks not possible on PAL.
2014-01-22 20:56
Peiselulli

Registered: Oct 2006
Posts: 81
But unfortunately I'm waiting for a test result on a drean machine since then ;-(
2014-01-22 21:47
chatGPZ

Registered: Dec 2001
Posts: 11100
Quote:
I'd love to see some Drean releases though, two extra cycles per line should allow for some neat tricks not possible on PAL.

i'd love to see one or two people who own such machines and are willing to run a bunch of testprogs - because everything in VICE regarding drean is pure guesswork :)
2014-01-23 00:28
Durandal

Registered: May 2006
Posts: 30
Quote: Quote:
I'd love to see some Drean releases though, two extra cycles per line should allow for some neat tricks not possible on PAL.

i'd love to see one or two people who own such machines and are willing to run a bunch of testprogs - because everything in VICE regarding drean is pure guesswork :)


Me, hedning and Thierry already did 3 years ago ;)

http://csdb.dk/forums/?roomid=7&topicid=73859#81066

(unless there's some new tests that need to be done on the Drean)
2014-01-23 00:49
chatGPZ

Registered: Dec 2001
Posts: 11100
there are a couple new ones... not exactly sure which though, tlr is the VIC guy =)
2014-01-24 18:00
tlr

Registered: Sep 2003
Posts: 1702
Quoting Groepaz
i'd love to see one or two people who own such machines and are willing to run a bunch of testprogs - because everything in VICE regarding drean is pure guesswork :)

It's not pure guesswork since those much valued tests The_WOZ, Thierry and hedning did.

It's far less verified than PAL emulation but not so far from NTSC emulation IMO. This goes for x64sc. For x64 all bets are off as usual.

Sorry for the late answer BTW. Was away watching Kraftwerk... ;)
2014-01-24 20:11
hedning

Registered: Mar 2009
Posts: 4584
I'm willing to test stuff on my drean if people need it. Just PM me.
2014-01-26 11:14
chatGPZ

Registered: Dec 2001
Posts: 11100
ok so that improved since last time i checked (which was the first and last time i ever run a supposedly drean specific program =P)

then instead everyone bug tlr about fixing that damned sprite x stretch bug =D
2014-01-26 12:58
tlr

Registered: Sep 2003
Posts: 1702
Quoting Groepaz
ok so that improved since last time i checked (which was the first and last time i ever run a supposedly drean specific program =P)

then instead everyone bug tlr about fixing that damned sprite x stretch bug =D

Please do... ;)

For the record: what's holding me back is that my win32 dev environment no longer builds the trunk since some automake updates were committed a long while ago.
(that and the fact that I am a bit too lazy :)
2020-11-06 21:26
hedning

Registered: Mar 2009
Posts: 4584
I'm still willing to test stuff on my Drean if people need it for working on better emulation. Just PM me.

I also have a NTSC 1983 250407 and a NTSC 1987 250466 hooked up in the lab.
2020-11-06 23:07
Krill

Registered: Apr 2002
Posts: 2825
I may have overlooked something, but it seems most (all?) previously mentioned approaches check the line counter wrap to determine the video system.

Seems like this approach hasn't been mentioned yet (executed with SEI and screen on), taken from some soon-to-be-released real-world code of mine, obviously still has some opportunities to save bytes:
            ldx #$fc
-           bit $d011
            bmi -
-           bit $d011
            bpl -
-           pha
            pla
            dex
            txa
            bne -
            ldx $d012
            cpx #$32
            rol
            cpx #$18
            rol
            eor #1
After execution, accu contains 0 for NTSC, 1 for PAL, 2 for PAL-N.

The technique is to wait a fixed number of cycles starting from line 256 (in the lower border), then read the current raster line counter. The delay must be long enough such that a new video frame is guaranteed to be reached (and should be short enough to stay in borderland and not bump into any badlines).

Since all four C-64 video systems differ in number of cycles per rasterline AND number of rasterlines per frame, each of them comes out on a different rasterline.

Could be enhanced for NTSC-new vs NTSC-old detection, but i don't need that for my purposes, and i'm lazy now. =)
2020-11-07 00:41
Copyfault

Registered: Dec 2001
Posts: 466
Did not check all former proposals, but tinkering around with NTSC lately, I used this for telling PAL&NTSC apart:
chk_ntsc:   ldx #TAX
            lda $d012
            bne chk_ntsc+1
            txa
            bmi chk_ntsc
This always ends on rasterline $000 with X(=A)-values
$05: NTSC (64 cycles)
$06: NTSC (65 cycles)
$37: PAL

Unfortunately, it's not possible to distinguish between EU-PAL and PAL-N, but it was the shortest one I could come up with and that suited my needs. Maybe of interest for someone...
2020-11-07 00:46
JackAsser

Registered: Jun 2002
Posts: 1987
Quote: Did not check all former proposals, but tinkering around with NTSC lately, I used this for telling PAL&NTSC apart:
chk_ntsc:   ldx #TAX
            lda $d012
            bne chk_ntsc+1
            txa
            bmi chk_ntsc
This always ends on rasterline $000 with X(=A)-values
$05: NTSC (64 cycles)
$06: NTSC (65 cycles)
$37: PAL

Unfortunately, it's not possible to distinguish between EU-PAL and PAL-N, but it was the shortest one I could come up with and that suited my needs. Maybe of interest for someone...


Nice!!!
2020-11-07 00:57
Krill

Registered: Apr 2002
Posts: 2825
Quoting Copyfault
Unfortunately, it's not possible to distinguish between EU-PAL and PAL-N
Aw. Nice routine, but i need PAL-N detection. =)
2020-11-07 01:03
Silver Dream !

Registered: Nov 2005
Posts: 107
Quote: Did not check all former proposals, but tinkering around with NTSC lately, I used this for telling PAL&NTSC apart:
chk_ntsc:   ldx #TAX
            lda $d012
            bne chk_ntsc+1
            txa
            bmi chk_ntsc
This always ends on rasterline $000 with X(=A)-values
$05: NTSC (64 cycles)
$06: NTSC (65 cycles)
$37: PAL

Unfortunately, it's not possible to distinguish between EU-PAL and PAL-N, but it was the shortest one I could come up with and that suited my needs. Maybe of interest for someone...


Freakin' C007!!

I often use videonorm detection along with TOD initialisation so my goto method is

https://codebase64.org/doku.php?id=base:efficient_tod_initialis..

which detects videonorm at almost zero extra cost but for standalone PAL/NTSC this is impressive :-)
2020-11-07 02:57
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Krill
Quoting Copyfault
Unfortunately, it's not possible to distinguish between EU-PAL and PAL-N
Aw. Nice routine, but i need PAL-N detection. =)
That can be helped ;)
chk_ntsc:    ldx #TAX
             lda $d012
             bne chk_ntsc+1
             txa
             bmi chk_ntsc
wait10lines: cmp #$37
             bne end_chk
             dex
             cpx $0a
             cpx #$0a
             bne wait10lines
             cpx $d012
             bne end_chk
             lda #00
end_chk:     and #$03
             rts
Ends with A (now != X)
$00: EU-PAL (63 cycles per line)
$01: old NTSC (64 cycles per line)
$02: standard NTSC (65 cycles per line)
$03: PAL-N (Dreany 65-cycles per one of the 312 lines)

Did not test thoroughly, but the waitloop should suffice to shift the cycle-pos to line $09 in case of a 65-cycles-per-line-system, for any cycle position the wait10lines-loop can start with. Bet it can be shortened even more, but... not this session, at least for me;)

Another minus: ends on different rasterlines ($00 on ntsc, $0a on PAL). Maybe a plus, depends on how you look at it...
2020-11-07 12:35
Copyfault

Registered: Dec 2001
Posts: 466
chk_ntsc:
        ldx #TAX
        lda $d012
        bne chk_ntsc+1
        txa
wait10lines:
        bmi chk_ntsc
        cmp #$37
        //pagebreak
        bne end_chk
        dex
        cpx #$0a
        bne wait10lines
        cpx $d012
        bne end_chk
        lda #00
end_chk:
        and #$03
        rts
The bmi can be "embraced" for the waitloop - 2 bytes saved;) - but a pagebreak is needed in this case.

Another approach could be to wait for a rasterline that exists on all systems (i.e.$fc), then wait for 63*63 cycles. The rasterline which we're in after such a waitloop should uniquely determine the system. I'll maybe try this later, should become even shorter than the above.
2020-11-07 12:47
Frantic

Registered: Mar 2003
Posts: 1627
As usual: Please feel free to add stuff like this to Codebase. Generations of C64 coders will thank you for all eternity. :)
2020-11-07 18:34
Silver Dream !

Registered: Nov 2005
Posts: 107
Quoting Copyfault
I'll maybe try this later, should become even shorter than the above.


<shameless_promo>
I guess getting shorter than
	LDA $D03E
	AND #$07

with BeamRacer would be more than difficult ;-)

000 - NTSC (6567R8 or 8562)
110 - PAL (6569 or 8565)
100 - PAL-N (6572)
011 - NTSC (6567R56A)
</shameless_promo>

But I still find this novelty method really cool.
2020-11-08 01:31
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Frantic
As usual: Please feel free to add stuff like this to Codebase. Generations of C64 coders will thank you for all eternity. :)
I will, but I have to dig out my password from the depth of disorder hell /o\

Meanwhile, I tried the wait-only-approach. This is how it looks like currently:
             sei
wait_lower:  
             bit $d011
             bpl wait_lower
             ldx #$fc
waitline:    cpx $d012
             bne waitline
             nop
             nop
wait40lines: lda $d012
             //pagebreak
             dex
             bne wait40lines
             and #$03
             rts
The two NOPs are disturbing, but without them the LDA $D012 inside of the waitloop can fetch the rasterline value too early in some cases (for EU-PAL). This way it delivers (values after AND listed):
$00: EU-PAL
$01: NTSC old
$02: PAL-N
$03: NTSC-new

I'm sure there are other possibilities for the loop length. But it's already quite short I think (@Silver Dream: and BeamRacer *is* cheating!!!;)).
2020-11-08 10:27
Peiselulli

Registered: Oct 2006
Posts: 81
maybe replace one nop with "ldy #$ff" and use "lda $d012-$ff,y" to get rid of the pagebreak ?
2020-11-08 13:18
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Peiselulli
maybe replace one nop with "ldy #$ff" and use "lda $d012-$ff,y" to get rid of the pagebreak ?
Wanted to let it be, but... maybe like this:
             sei
             ldy #$01
             ldx #$fc
waitline:    cpx $d012
             bne waitline
             dey
             bpl waitline
wait40lines: lda $d012-$ff,y
             dex
             bne wait40lines
             and #$03
             rts
The double-check of line $fc should ensure that we do not leave it "inbetween". Downside: we also need y-reg, but the pagebreak is gone \o/
2020-11-08 13:58
Frantic

Registered: Mar 2003
Posts: 1627
Quoting copyfault
Downside: we also need y-reg


I'd say this type of code is typically executed in a context where it is not a problem if many sid registers are (ab)used, like.. some init code somewhere or so. So the use of the y-register isn't much of a drawback here, I guess?
2020-11-08 14:06
chatGPZ

Registered: Dec 2001
Posts: 11100
many sid registers
coffee!
2020-11-08 14:10
Frantic

Registered: Mar 2003
Posts: 1627
Ah.. Haha.. yes, maybe I should have a cup of coffee to wake up properly. I obviously meant cpu registers.
2020-11-08 14:23
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Frantic
Ah.. Haha.. yes, maybe I should have a cup of coffee to wake up properly. I obviously meant cpu registers.
You were hearing the melody of that code, weren't you *rotfl*

By the way, I think y must be init'ed with a higher value since it might not be enough to double-check line $fc.

Before porting it to codebase I'll check it at least on vice with the different VIC-type settings.


Aaaand: coffee ftw!!!
2020-11-08 20:55
Copyfault

Registered: Dec 2001
Posts: 466
The idea with checking the same line multiple times was crap! We need to ensure (somehow) that we start at a line that exists on all systems and is unique AND that the edge case of starting the routine while IN this specific line is avoided/handled. No matter what value we choose for y, there will still be cases that lead to a wrong starting situation.

So here comes my final (and hopefully robust-as-f*ck) version:
chk_victype: sei
             ldy #$04
ld_DEY:      ldx #DEY     //DEY = $88
waitline:    cpy $d012
             bne waitline
             dex
             bmi ld_DEY + 1
wait40lines: lda $d012 - $7f,x
             dey
             bne wait40lines
             and #$03
             rts
If someone with real machines wants to volunteer to test it, send me a pm. Ah, and I'll feed codebase within the next days, promised!
2020-11-09 07:36
Knight Rider

Registered: Mar 2005
Posts: 114
I have all 4 machines.
2020-11-10 10:30
Knight Rider

Registered: Mar 2005
Posts: 114
Results submited by PM
2020-11-10 14:14
hedning

Registered: Mar 2009
Posts: 4584
Yup. Sent 4 screenshots from 4 machines as well.
2020-11-10 17:49
Frantic

Registered: Mar 2003
Posts: 1627
It is good to hear that you are sending lots of messages to each other. ;) Now I am also curious to hear if the routine seemed to work well or not? :)
2020-11-10 17:50
hedning

Registered: Mar 2009
Posts: 4584
Quote: It is good to hear that you are sending lots of messages to each other. ;) Now I am also curious to hear if the routine seemed to work well or not? :)

I can send you a Pm too. :D
2020-11-10 17:52
Frantic

Registered: Mar 2003
Posts: 1627
Thanks for the offer, but on careful consideration I have come to the conclusion that I am primarily interested to hear if the aforementioned routine seemed to work well or not. Does that constitute a type of information that you would be willing to share, publicly, in a forum discussion thread like the present one?
2020-11-10 19:27
hedning

Registered: Mar 2009
Posts: 4584
Quote: Thanks for the offer, but on careful consideration I have come to the conclusion that I am primarily interested to hear if the aforementioned routine seemed to work well or not. Does that constitute a type of information that you would be willing to share, publicly, in a forum discussion thread like the present one?

Ah. No. I'll leave that to Copyfault. But I was was told my screenshots made him very happy.
2020-11-10 20:55
Knight Rider

Registered: Mar 2005
Posts: 114
My videos produced the desired results on all 4 machines.
2020-11-11 02:06
Copyfault

Registered: Dec 2001
Posts: 466
First of all: thanks to the testers!!! The routine behaves as it should on all tested real machines: in total 3 with new NTSC-VIC, one with old NTSC, two Drean-systems and two EU-PAL-systems (not counting my own system here).

So I think it's save to say the routine works. I just wrote up a (rather longish, sorry) explanation on codebase (-> yes, pswd has been found \o/).


Feel free to edit it or drop me a comment via pm if you think it should be changed/shortened/extended...
2020-11-11 07:57
Knight Rider

Registered: Mar 2005
Posts: 114
I am sure the purists will argue that the SEI in the routine could lead to false results in some circumstances
2020-11-11 10:54
JackAsser

Registered: Jun 2002
Posts: 1987
Really elegant! I might switch to that. Currently in Eye of the Beholder I use a timer and wait for a while, then check what raster line I'm on:
		sei
		lda #0
		sta $d011
		sta $dc0e
		sta $dc0f
		bit $d011
		bpl *-3
		bit $d011
		bmi *-3

		lda #$7f
		sta $dc0d
		bit $dc0d

		lda #<(16384-1)
		sta $dc04
		lda #>(16384-1)
		sta $dc05
		lda #%10011001

		bit $d011
		bpl *-3
		
		sta $dc0e

		:lda $dc0d
		beq :-
		lda $d012

		ldx #SYSTEM_PAL ;SYSTEM_UNKNOWN (default PAL and live with gfx glitches instead of total crash)
		cmp #$cc
		bne :+
			ldx #SYSTEM_PAL
		:
		cmp #$f5
		bne :+
			ldx #SYSTEM_NTSC
		:
		cmp #$fa
		bne :+
			ldx #SYSTEM_NTSC_OLD
		:
		cmp #$c4
		bne :+
			ldx #SYSTEM_DREAN
		:
		stx system
2020-11-11 14:39
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Knight Rider
I am sure the purists will argue that the SEI in the routine could lead to false results in some circumstances
Well, the SEI was the smallest solution to switch off IRQs (besides NMI ofcourse). As mentioned in the introductory text for the full VIC-detection routine, the routine requires to be run in a badline- and IRQ-free environment. Since such a VIC-detect-routine is usually called when initialising also other things, I don't think the SEI is a real problem here - depending on how you arrange your overall init code, it could even be ommitted.


Quoting JackAsser
Really elegant! I might switch to that.
...
Thanks! Feel free to use it if it improves things on the project. Ah, and thanks for sharing your code;)
2020-11-11 14:40
Krill

Registered: Apr 2002
Posts: 2825
Quoting JackAsser
then check what raster line I'm on:
		[...]
		bne :+
		[...]
		bne :+
		[...]
Is there a specific reason to check for equality rather than ranges? =)
2020-11-11 14:53
Krill

Registered: Apr 2002
Posts: 2825
Quoting Copyfault
So here comes my final (and hopefully robust-as-f*ck) version:
chk_victype: sei
             ldy #$04
ld_DEY:      ldx #DEY     //DEY = $88
waitline:    cpy $d012
             bne waitline
             dex
             bmi ld_DEY + 1
wait40lines: lda $d012 - $7f,x
             dey
             bne wait40lines
             and #$03
             rts
Does this boil down to the same basic approach i suggested in https://csdb.dk/forums/?roomid=11&topicid=94459#146098 - but squeezed for size? =)
2020-11-11 15:32
JackAsser

Registered: Jun 2002
Posts: 1987
Quote: Quoting JackAsser
then check what raster line I'm on:
		[...]
		bne :+
		[...]
		bne :+
		[...]
Is there a specific reason to check for equality rather than ranges? =)


Not really no, but bcc and bcs are so complicated. :D
2020-11-11 15:39
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Krill
[...]Does this boil down to the same basic approach i suggested in https://csdb.dk/forums/?roomid=11&topicid=94459#146098 - but squeezed for size? =)
Correct! I pointed this out in the text I wrote on codebase, i.e. that the idea was brought up by a certain Krill;)

Have to admit that I had this idea on my own but it took me some days until I fully realised that this idea was not new at all, but rather the reason for your post here in the thread (see link above). Well, that tunnel thing /o\
2020-11-11 21:22
Krill

Registered: Apr 2002
Posts: 2825
Quoting JackAsser
Not really no, but bcc and bcs are so complicated. :D
Though you were obviously joking... i use to picture CMP as just an SBC that doesn't store the result and has a built-in SEC. Then it becomes quite easy to decide between BCS (A/X/Y >= value) and BCC (A/X/Y < value). :)
2020-11-11 21:38
Frantic

Registered: Mar 2003
Posts: 1627
Quote: Quoting JackAsser
Not really no, but bcc and bcs are so complicated. :D
Though you were obviously joking... i use to picture CMP as just an SBC that doesn't store the result and has a built-in SEC. Then it becomes quite easy to decide between BCS (A/X/Y >= value) and BCC (A/X/Y < value). :)


Hehe.. Yeah, that's exactly how I think about it as well. So far so good, but if we talk about the v-flag instead (as associated with bvc/bvs), I have to confess that it is much less clear to me how to conceptualize it. Sometimes I use it with the BIT instruction, but then I just treat it as... a bit, e.g. a way to check the status of bit6. Using it with ADC/SBC is another issue. Anyway, back to topic. :)
2020-11-11 21:44
TWW

Registered: Jul 2009
Posts: 541
Should also work:


// NTSC Old:		00
// PAL:			01
// Drean:		10
// NTSC:		11

    ldx #%10011001
    stx $dc04
    stx $dc05
    cpx $d012
    bne *-3
    stx $dc0e
    dex
    cpx $d012
    bne *-3
    lda $dc05
    and #%00000011



There is probably a 'magic' value one can use to omit setting dc04 and bring this down to 10 lines of code but it's still more bytes so I can't be bothered :). It get's the job done in less than a frame though^^

If you have VSYNC somewhere else in your code, you could substitute the cpx/bne and dex/cpx/bne for two jsr'r but I guess that is cheating in this context.
2020-11-11 21:48
Krill

Registered: Apr 2002
Posts: 2825
Quoting Frantic
Hehe.. Yeah, that's exactly how I think about it as well. So far so good, but if we talk about the v-flag instead (as associated with bvc/bvs), I have to confess that it is much less clear to me how to conceptualize it. Sometimes I use it with the BIT instruction, but then I just treat it as... a bit, e.g. a way to check the status of bit6. Using it with ADC/SBC is another issue. Anyway, back to topic. :)
Sorry for staying off-topic for another post. :)

The V-flag can only be set if the signs of both operands match. And then it gets set if the result's sign is the opposite of both operands' sign.

I.e., adding two positive numbers and getting a negative result would be... unexpected in certain scenarios, thus overflow. :D

(Analogous with subtraction.)

HTH! :D (And also hope i got it right.)
2020-11-12 08:24
JackAsser

Registered: Jun 2002
Posts: 1987
Quote: Should also work:


// NTSC Old:		00
// PAL:			01
// Drean:		10
// NTSC:		11

    ldx #%10011001
    stx $dc04
    stx $dc05
    cpx $d012
    bne *-3
    stx $dc0e
    dex
    cpx $d012
    bne *-3
    lda $dc05
    and #%00000011



There is probably a 'magic' value one can use to omit setting dc04 and bring this down to 10 lines of code but it's still more bytes so I can't be bothered :). It get's the job done in less than a frame though^^

If you have VSYNC somewhere else in your code, you could substitute the cpx/bne and dex/cpx/bne for two jsr'r but I guess that is cheating in this context.


Really neat!
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Mr SQL
Guests online: 62
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 The Ghost  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 It's More Fun to Com..  (9.9)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 Rainbow Connection  (9.5)
6 TRSAC, Gabber & Pebe..  (9.5)
7 Onscreen 5k  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Nostalgia  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Organizers
1 Burglar  (9.9)
2 Sixx  (9.8)
3 hedning  (9.7)
4 Irata  (9.7)
5 MWS  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.147 sec.