| |
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
|
|
| |
Devia
Registered: Oct 2004 Posts: 401 |
How many lines does the Drean have?
And is the Drean 6572 or 6573?
|
| |
tlr
Registered: Sep 2003 Posts: 1787 |
Nice detection code!
@devia: 312 lines. |
| |
Moloch
Registered: Jan 2002 Posts: 2924 |
Nice detection routine, will have to give it some testing.
Quoting DeviaHow 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/ |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Works perfectly using Vice 2.4.
Chapeau. |
| |
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 ?
|
| |
hedning
Registered: Mar 2009 Posts: 4720 |
I could try to, tomorrow. Oh. It is already tomorrow. Later today that is, then. :) |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
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. |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
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 |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
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
|
| |
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? |
| |
Burglar
Registered: Dec 2004 Posts: 1085 |
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! |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
IIRC $02a6 is far from reliable. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
You forgot a SEI.
If an irq is fired in the middle of the loop... all fucks. |
| |
Ninja
Registered: Jan 2002 Posts: 411 |
Burglar: Two reasons given here: http://www.the-dreams.de/articles/pal-ntsc-detector.txt |
| |
Fungus
Registered: Sep 2002 Posts: 680 |
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 |
| |
chatGPZ
Registered: Dec 2001 Posts: 11350 |
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 :) |
| |
TWW
Registered: Jul 2009 Posts: 545 |
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. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
@TWW: Clean! |
| |
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 |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
Quoting TWWI 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. |
| |
MagerValp
Registered: Dec 2001 Posts: 1074 |
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
|
| |
Peiselulli
Registered: Oct 2006 Posts: 81 |
@MagerValp : But the main reason for starting this thread is missing : detection between "drean" an "pal". |
| |
TWW
Registered: Jul 2009 Posts: 545 |
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
|
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
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? |
| |
Fungus
Registered: Sep 2002 Posts: 680 |
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 ;) |
| |
MagerValp
Registered: Dec 2001 Posts: 1074 |
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. |
| |
Peiselulli
Registered: Oct 2006 Posts: 81 |
But unfortunately I'm waiting for a test result on a drean machine since then ;-( |
| |
chatGPZ
Registered: Dec 2001 Posts: 11350 |
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 :) |
| |
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) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11350 |
there are a couple new ones... not exactly sure which though, tlr is the VIC guy =) |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
Quoting Groepazi'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... ;) |
| |
hedning
Registered: Mar 2009 Posts: 4720 |
I'm willing to test stuff on my drean if people need it. Just PM me. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11350 |
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 |
| |
tlr
Registered: Sep 2003 Posts: 1787 |
Quoting Groepazok 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 :) |
| |
hedning
Registered: Mar 2009 Posts: 4720 |
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. |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
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. =) |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
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... |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
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!!! |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
Quoting CopyfaultUnfortunately, it's not possible to distinguish between EU-PAL and PAL-N Aw. Nice routine, but i need PAL-N detection. =) |
| |
Silver Dream !
Registered: Nov 2005 Posts: 108 |
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 :-) |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting KrillQuoting CopyfaultUnfortunately, 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... |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
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. |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
As usual: Please feel free to add stuff like this to Codebase. Generations of C64 coders will thank you for all eternity. :) |
| |
Silver Dream !
Registered: Nov 2005 Posts: 108 |
Quoting CopyfaultI'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. |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting FranticAs 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!!!;)). |
| |
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 ? |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting Peiselullimaybe 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/ |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
Quoting copyfaultDownside: 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? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11350 |
many sid registers
coffee! |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
Ah.. Haha.. yes, maybe I should have a cup of coffee to wake up properly. I obviously meant cpu registers. |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting FranticAh.. 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!!! |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
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! |
| |
Knight Rider
Registered: Mar 2005 Posts: 131 |
I have all 4 machines. |
| |
Knight Rider
Registered: Mar 2005 Posts: 131 |
Results submited by PM |
| |
hedning
Registered: Mar 2009 Posts: 4720 |
Yup. Sent 4 screenshots from 4 machines as well. |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
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? :) |
| |
hedning
Registered: Mar 2009 Posts: 4720 |
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 |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
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? |
| |
hedning
Registered: Mar 2009 Posts: 4720 |
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. |
| |
Knight Rider
Registered: Mar 2005 Posts: 131 |
My videos produced the desired results on all 4 machines. |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
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... |
| |
Knight Rider
Registered: Mar 2005 Posts: 131 |
I am sure the purists will argue that the SEI in the routine could lead to false results in some circumstances |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
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
|
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting Knight RiderI 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 JackAsserReally 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;) |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
Quoting JackAsserthen check what raster line I'm on:
[...]
bne :+
[...]
bne :+
[...]
Is there a specific reason to check for equality rather than ranges? =) |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
Quoting CopyfaultSo 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? =) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Quoting JackAsserthen 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 |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
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\ |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
Quoting JackAsserNot 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). :) |
| |
Frantic
Registered: Mar 2003 Posts: 1646 |
Quote: Quoting JackAsserNot 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. :) |
| |
TWW
Registered: Jul 2009 Posts: 545 |
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. |
| |
Krill
Registered: Apr 2002 Posts: 2968 |
Quoting FranticHehe.. 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.) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
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! |