Wilheim Posted February 27, 2020 Share Posted February 27, 2020 (edited) Hi, everyone! Due that by this time we have a lot of NTSC and PAL users, and increasingly the coders are supporting both formats, I would like to discuss something about it. Currently, the majority of the programs that adjust PAL/NTSC timers are based on detecting the PAL address ($D014) on the GTIA, then if its NTSC or PAL, adjust the timers and colors if necessary. That would work for about 99% of the Atari 8-bit machines, but unfortunately it doesn't work, for example, to NTSC computers that the ANTIC is swapped from NTSC to PAL. The timers are adjusted for NTSC but running at a 50 Hz screen rate. Because of that, I would like to propose a standard to adjust timers and/or colors. 1.- Detecting ANTIC instead of GTIA for NTSC/PAL timing. 2.- Using PAL address of the GTIA to adjust colors. According to the XL/XE memory map from Mapping the Atari, the address $62 is used for PAL/NTSC timing. Maybe we could use that address for that purpose and modifying it when detecting the ANTIC type. Based on these principles, I would like to share a small routine to detect if the ANTIC is PAL or NTSC. It's just an example that writes on screen if the ANTIC is NTSC or not. The routine just takes the maximum scanline detected by VCOUNT. If it's less than 135, then the ANTIC is NTSC. Otherwise, is PAL. I will appreciate any feedback about it, as well as any suggestion to improve this proposal. Regards! paltest-v2.asm Edited February 27, 2020 by Wilheim Relocating attached file 3 1 Quote Link to comment Share on other sites More sharing options...
mono Posted February 27, 2020 Share Posted February 27, 2020 In Polish, but Google should to deal with it: http://atariki.krap.pl/index.php/Programowanie:_Jak_wykryć_system_TV Do you have any idea how to detect SECAM? Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 27, 2020 Share Posted February 27, 2020 (edited) We discussed this some years back and came to the same conclusion - the scanline method. It works well for an initial decision but we have the problem of emulation where it can be changed on the fly and it's not really practical to check the max scanline count every frame. The PAL register method is good in that you can easily take the value and manipulate it with a couple of extra instructions to create an index. SECAM - There isn't an easy way to detect it. The one difference with SECAM is that since multiple pins were reassigned for the video output, there's only a single TRIG input which is fed each scanline by a shift register. As such, I'd propose an detection method: - get the user to press the joystick fire button a few times (this could be part of a skip intro sequence before entering the game) - on SECAM the TRIG value should only change at an early part of the scanline which should be the same every time. - have your program wait for TRIG=0 while in a loop, hitting WSYNC and counting up an index register so we have an approximate scanline hpos. - if the TRIG transitions are all occurring at the same index value then we're likely running on SECAM. Edited February 27, 2020 by Rybags Quote Link to comment Share on other sites More sharing options...
mono Posted February 28, 2020 Share Posted February 28, 2020 @Rybags: Thanks a lot. Quote Link to comment Share on other sites More sharing options...
R0ger Posted February 28, 2020 Share Posted February 28, 2020 I was under impression that SECAM basically does not need to be detected, it behaves in all aspects like PAL. Am I wrong ? Quote Link to comment Share on other sites More sharing options...
mono Posted February 28, 2020 Share Posted February 28, 2020 @R0ger: Two issues: 1. I'm not sure colors are the same in PAL and SECAM. My observation is that vertical scroll by one scanline changes colour on SECAM, although doesn't it on PAL (maybe it's connected with LCD monitor I've used - LG FLATRON M1917A; I haven't tested it on CRT yet). 2. Let's say that you need to know exact frequency of CPU, because you need to generate exact 1 kHz wave (there is no possibility of manual tuning). How to do this without detection of CPU speed (TV system in this case, because all I/O devices are clocked by the same frequency as CPU)? They're just theoretical examples, but knowledge about TV system can be used to correction of game colors (once you develop your game) or when you use Atari as audio device playing unisono with other devices of different kind and clocked by completelly different frequency. Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 28, 2020 Share Posted February 28, 2020 (edited) I've never seen a Secam system for real but would guess the colours are different. The CPU speed - that's one thing we probably can't deduce for sure since you could mix/match Antic and GTIA with foreign master clocks - I should think the difference would be tolerated by most TVs. I'm not aware of any music though that caters for clock speed differences WRT it's note playback, only stuff that always plays at ~ 50 Hz by skipping every 6th frame if the system is at the NTSC framerate. Edited February 28, 2020 by Rybags Quote Link to comment Share on other sites More sharing options...
tane Posted February 28, 2020 Share Posted February 28, 2020 (edited) Hi, What should be changed in the end to do something like loading PAL.xex or NTSC.xex accordingly?: mensaje_pal // .by "PAL!!" .by $9b opt h- ins 'PAL.xex' opt h+ mensaje_ntsc // .by "NTSC!!" .by $9b opt h- ins 'NTSC.xex' opt h+ max .byte 0 .endp run init Edited February 28, 2020 by tane Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 28, 2020 Share Posted February 28, 2020 @tane, that would be overkill as 99% of the code and data is going to be the same To the most part I've found the simple PAL register check to be fine but would agree that the scanline check is better due to machines that can handle switchable customer chips and clocks. Where needed you can set variables appropriately, e.g. for the Doom-Fire demo I used this: (DETECT = $D014) .proc SetColours LDA DETECT ; reads PAL/NTSC AND #2 BEQ @+ LDA #$10 @: STA c0 CLC LDA #0 STA PCOLR0 LDA #$30 ADC c0 STA PCOLR1 LDA #$32 ADC c0 STA PCOLR2 LDA #$22 ADC c0 STA PCOLR3 LDA #$24 ADC c0 STA COLOR0 LDA #$26 ADC c0 STA COLOR1 LDA #$28 ADC c0 STA COLOR2 LDA #$EA ADC c0 STA COLOR3 LDA #$EC ADC c0 STA COLOR4 ; LDA #$80 STA GPRIOR RTS .endp For music though this is more tricky, so for a more professional production both a NTSC and a PAL version could be built to same address. For example, in a MADS built xex you could then use a 'ini' section to load the second to another address, decide if it is needed, copy over the first if it is, then continue the load. 1 Quote Link to comment Share on other sites More sharing options...
tane Posted February 29, 2020 Share Posted February 29, 2020 (edited) 2 hours ago, Wrathchild said: that would be overkill as 99% of the code and data is going to be the same Agree and disagree, it depends on the situation. If you're writing from scratch I totally agree not to have duplicates. But for hacks, if the original is for example NTSC and you want to make a PAL version with the "right" colors, it's easy just to make a duplicate, it can be done in a few minutes without disassembling the code, and without a full knowledge of the language. If you're not a good coder in assembler, the first, and also the most professional option, is no way. So, having a NTSC.xex and a PAL.xex, and if the size is small, it's very useful a code to join them in one single file. That's what I'm looking for at this stage. So, regarding the code of the first post, that by the way its publication is very useful, what should be changed to do something like loading PAL.xex or NTSC.xex accordingly? (first post code: paltest-v2.asm) I did some changes with the following, but no luck. opt h- ins 'PAL.xex' opt h+ opt h- ins 'NTSC.xex' opt h+ Edited February 29, 2020 by tane Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 29, 2020 Share Posted February 29, 2020 Not sure what you are trying here, 'ins' includes the binary in the resulting object and so you are copying both into the result binary but without wrapping them with any labels to later relocate them? Going back to a hack of an existing binary, the result is having the two files. But that can be seen as 'being lazy' and can be taken a stage further and a diff of the files produces a delta which can be translated into a form (e.g. table of addresses and values) that can be turned into a small binary that runs through the table and applies the values. That is then injected back into the original binary instead of the 'run' block. Voila, you have a single binary that caters for both platforms. Quote Link to comment Share on other sites More sharing options...
tane Posted February 29, 2020 Share Posted February 29, 2020 4 minutes ago, Wrathchild said: Not sure what you are trying here, 'ins' includes the binary in the resulting object and so you are copying both into the result binary but without wrapping them with any labels to later relocate them? I'm trying to include both binaries. One should be loaded in a NTSC system, and the other in a PAL system, automatically. An of course the code is not complete, that's why I'm asking what must be changed /added in the post #8. 8 minutes ago, Wrathchild said: Going back to a hack of an existing binary, the result is having the two files. But that can be seen as 'being lazy' and can be taken a stage further Is not the best solution, but is a good solution with what is available to do. If you go to a highway and start asking the driver why you are not driving a car of 300 km/hr of maximum speed, you'll have the same answer: "This is better instead of walking". So what should be added to the code of the post #8 for this "second class, still working" solution? Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted February 29, 2020 Share Posted February 29, 2020 5 minutes ago, tane said: One should be loaded in a NTSC system, and the other in a PAL system, automatically. You can't do that as (presumably) they occupy the same address 15 hours ago, Wrathchild said: in a MADS built xex you could then use a 'ini' section to load the second to another address, decide if it is needed, copy over the first if it is, then continue the load. this approach would satisfy that but then this is limiting the size to half of the available memory. Quote Link to comment Share on other sites More sharing options...
tane Posted February 29, 2020 Share Posted February 29, 2020 20 minutes ago, Wrathchild said: You can't do that as (presumably) they occupy the same address Ok, thank you. So is not a straightforward approach as I was thinking, just as inserting the binaries in the code. This is the original file I was working on: River Raid (1983)(Activision)(US)[a4].xex , so in order to have a PAL and a NTSC version, with customs colors each, I'll have to do 2 different files (PAL.xex & NTSC.xex), instead of having at the end, 1 file with all together. Quote Link to comment Share on other sites More sharing options...
Wilheim Posted February 29, 2020 Author Share Posted February 29, 2020 7 hours ago, tane said: Ok, thank you. So is not a straightforward approach as I was thinking, just as inserting the binaries in the code. This is the original file I was working on: River Raid (1983)(Activision)(US)[a4].xex , so in order to have a PAL and a NTSC version, with customs colors each, I'll have to do 2 different files (PAL.xex & NTSC.xex), instead of having at the end, 1 file with all together. I think I understand your intention: to have two binaries of the game for PAL or NTSC and run the right one for each case. IIRC, in this case in particular, River Raid detects PAL or NTSC machines at the beginning. The same goes for Pitfall II. By the way, the ATR image of Yoomp! does the PAL/NTSC detection by GTIA. I think it would be interesting to change the detection routine, so the correct version will load. Quote Link to comment Share on other sites More sharing options...
tane Posted March 1, 2020 Share Posted March 1, 2020 1 hour ago, Wilheim said: IIRC, in this case in particular, River Raid detects PAL or NTSC machines at the beginning. Mmmm..., but then when running in both systems there are different speeds and colors, i.e. there is only one speed and color in the code. Quote Link to comment Share on other sites More sharing options...
+slx Posted March 7, 2020 Share Posted March 7, 2020 I tried to use the VCOUNT method in Altirra. Running from a default graphics 0 "blue screen" and loading VCOUNT as the first instruction of an immediate VBLANK routine VCOUNT is $7C regardless of PAL or NTSC being selected for emulation. Any ideas? Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 7, 2020 Share Posted March 7, 2020 The VBlank interrupt occurs after the normal 240 scanline display which is why you get the same result. A reliable method is to do compare/load until the new value goes back to positive. e.g. START BIT VCOUNT BPL START WAIT1 LDA VCOUNT BPL VBOVER TAX BMI WAIT1 VBOVER CPX #$90 LDA #0 ADC #0 STA PALFLAG It's the best way as there's no possibility of having DLIs in the region where the extra PAL scanlines occur. Disadvantage is that it's not practical to run every VBlank (in case of emulator on the fly changes). In such a case a Pokey Timer could be used to minimize the CPU burden but then you're dedicating an audio channel to that task which isn't practical either. 1 1 Quote Link to comment Share on other sites More sharing options...
+slx Posted March 7, 2020 Share Posted March 7, 2020 5 hours ago, Rybags said: Disadvantage is that it's not practical to run every VBlank (in case of emulator on the fly changes). In such a case a Pokey Timer could be used to minimize the CPU burden but then you're dedicating an audio channel to that task which isn't practical either. Thanks, it's perfect for me as I only need it during intitialization so it needs to run only once. Quote Link to comment Share on other sites More sharing options...
tane Posted May 23, 2021 Share Posted May 23, 2021 Some progress with the language. ? // Color and Speed Test for Atari 8-bits ; Results: ; ; Test | COLOR.ADDRESS | SPEED.ADDRESS | ; -----------------------|---------------|---------------| ; NTSC-60 (default NTSC) | 00 | 60 | ; NTSC-50 | 00 | 50 | ; PAL-60 | 01 | 60 | ; PAL-50 (default PAL) | 01 | 50 | ; ; GTIA ($d014): NTSC colors: 0f ; PAL colors: 01 ORG.ADDRESS = $4000 ;Location of this code SPEED.ADDRESS = $42ff ;EDIT: Address of the mark of the speed (50 if PAL, 60 if NTSC) -> EDIT address COLOR.ADDRESS = $42fe ;EDIT: Address of the mark of the color (01 if PAL, 00 if NTSC) -> EDIT address vcount =$d40b ;vertical line counter org ORG.ADDRESS .proc paltest start loop1 lda vcount cmp #100 bcc loop1 //Wait till scanline 200 sta max loop2 lda vcount cmp #10 bmi loop2.fin cmp max bmi loop2 sta max bpl loop2 loop2.fin ldx #$60 ; 60 = NTSC default lda max cmp #135 bmi ntsc.test ldx #$50 ; 50 = PAL default ntsc.test stx SPEED.ADDRESS lda $d014 ; GTIA (color) cmp #$01 ; 01=PAL, 0f=NTSC beq it.is.color.pal lda #$00 ; 00=NTSC sta COLOR.ADDRESS rts it.is.color.pal lda #$01 ; 01=PAL sta COLOR.ADDRESS rts max .byte 0 .endp ini ORG.ADDRESS 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted May 23, 2021 Share Posted May 23, 2021 On 2/27/2020 at 11:27 PM, Rybags said: It works well for an initial decision but we have the problem of emulation where it can be changed on the fly and it's not really practical to check the max scanline count every frame. I think the games should be made to work as well as possible on real machines. No one expects emulation to be perfect, and reloading a game after an emulator change takes 2 secs. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.