Testing interlaced code; no real hardware to hand

General Programming help in C, C++ or ASM, Compiling / Debugging, and R3000A Central Processing Unit (CPU) information
Post Reply
Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Testing interlaced code; no real hardware to hand

Post by Tommy » May 11th, 2014, 10:41 am

Either none of the available emulators do a proper job of interlaced mode or I'm not doing a proper job of interlaced mode. Can anyone help me figure out which?

I'm using No$PSX primarily, as it just about works under WINE, but found that although my dfe flag is definitely set, ignoring the documentation's admonition that drawing within vsync will produce the incorrect results on 50% of fields produces no visible problems. Furthermore I'm using interlaced mode as per the TV norm, with fields being offset both vertically and in time but can see no bad weave in the VRAM viewer.

Furthermore it's just one solid colour triangle so I'm pretty much definitely getting it done within the VRAM period. If I were to remove my GetODE checks I would therefore assume it would vanish every other field.

The other emulators that I've tried give no indication they're doing any sort of real hardware emulation at all. They're the usual pile of plug-ins and hacks that only the author could love.

My .exe is attached in case anybody is both willing and able quickly to squirt it over to a real machine, in which case I'll be eternally grateful; otherwise can anyone nominate a suitable emulator or think of any other way I could test my little bit of code? It's kind of a fundamental thing, that I'd like to be confident is correct before I move on.
You do not have the required permissions to view the files attached to this post.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » May 11th, 2014, 4:58 pm

I tested it on my 5502 for you and what I got is a little different from the emulator.
First off, I needed to adjust my 1084S monitor as the display appears to be 640x480 resolution since the FntPrint() size is really small. Secondly, I noticed that the polygon rendering was significantly slower. In fact, it was really slow. I saw the header info within the PS-EXE, and it says "Sony Computer Entertainment Inc. for Europe area", so I assume you compiled it as a PAL PS-EXE.

Here is a screenshot (it's the best I could do with my camera):
Image

I could make a video of a screen capture for you, but I need to setup my capture equipment. Let me know if you want me to do this for you and I'll go ahead and record it. I highly recommend however getting a PSX setup with a modchip and PSXSERIAL for now.
You do not have the required permissions to view the files attached to this post.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Post by Tommy » May 12th, 2014, 12:00 am

Shadow wrote:I tested it on my 5502 for you and what I got is a little different from the emulator.
First off, I needed to adjust my 1084S monitor as the display appears to be 640x480 resolution since the FntPrint() size is really small. Secondly, I noticed that the polygon rendering was significantly slower. In fact, it was really slow. I saw the header info within the PS-EXE, and it says "Sony Computer Entertainment Inc. for Europe area", so I assume you compiled it as a PAL PS-EXE.
Thanks! Yes, it's 640x480 PAL but the number within the square brackets implies it was running at the correct speed: that's the count of how many fields were output before a new drawing list was prepared — the frame rate compensation number. 1 is ideal. It moves that one vertex by a single pixel per field so at PAL speed you'd expect it to take 12.8 seconds to cross the screen.

But never mind that, thanks again. It seems to me that interlaced mode is the main thing I'd need to test on a real machine before writing a whole bunch of further code that can be emulator tested and then switching back to a real machine. But it's also the very first piece of code so possibly I'm lying to myself and will just continue to hit brick wall after brick wall...
Shadow wrote:Here is a screenshot (it's the best I could do with my camera): ...
I could make a video of a screen capture for you, but I need to setup my capture equipment. Let me know if you want me to do this for you and I'll go ahead and record it. I highly recommend however getting a PSX setup with a modchip and PSXSERIAL for now.
I feel like I've imposed enough but I can't thank you enough for the offer. Assuming the ~13 seconds for the vertex to cross the screen sounds approximately right, I'm happy. Or even if you never comment again I'm already very happy!

My issues with getting a real machine are that (i) I don't have a TV or space for a CRT; (ii) I'm normally a PAL resident but am temporarily resident in an NTSC country, currently without any idea for how long; and (iii) my computer doesn't have serial ports. Honestly, I have the resources to fix all of these problems but I'm mainly holding back on (ii) as I should know whether it's more like two months or more like eighteen months shortly.

On that topic, I'm tempted to grab a 'Test' PS2 slim as I understand they're region free and the power supply is external so they're much more portable between regions — no need for a step down transformer, just buy a different AC adaptor. Do those play PS1 CDRs? I know that producing a full CD is a hassle, seemingly not achievable from a script (?), and testing via one obviously isn't ideal, but it seems like a good temporary compromise. Otherwise presumably I'm looking for a modded or 'Test' PS1, something that is or can be flashed to Caetla and a USB serial port?

Thanks a third time!

EDIT: obviously a PSIO would resolve all issues but in the meantime: can I use one of those PSOne LCDs on a full-size PlayStation?

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » May 12th, 2014, 3:59 pm

Tommy wrote:My issues with getting a real machine are that (i) I don't have a TV or space for a CRT; (ii) I'm normally a PAL resident but am temporarily resident in an NTSC country, currently without any idea for how long; and (iii) my computer doesn't have serial ports. Honestly, I have the resources to fix all of these problems but I'm mainly holding back on (ii) as I should know whether it's more like two months or more like eighteen months shortly.

On that topic, I'm tempted to grab a 'Test' PS2 slim as I understand they're region free and the power supply is external so they're much more portable between regions — no need for a step down transformer, just buy a different AC adaptor. Do those play PS1 CDRs? I know that producing a full CD is a hassle, seemingly not achievable from a script (?), and testing via one obviously isn't ideal, but it seems like a good temporary compromise. Otherwise presumably I'm looking for a modded or 'Test' PS1, something that is or can be flashed to Caetla and a USB serial port?

Thanks a third time!

EDIT: obviously a PSIO would resolve all issues but in the meantime: can I use one of those PSOne LCDs on a full-size PlayStation?
(i) You can get a USB AV capture card for ~$10 on eBay. I use VLC to stream the video.
(ii) Applies to (i).
(iii) You use a FTDI (the FTDI-RL is prefered) USB Serial Adapter.

Yes, you can use a PSone LCD Screen on any PSX, but it will require modification. More so in the terms of opening it up and extending the male MULTI-AV port so you can actually plug it in. It would work, but be very pointless and annoying since it wont stand itself upright because there are not mounting holes to secure it to.

Buy this: USB Capture Card (eBay Auction)
And buy this: FTDI-RL USB Adapter (eBay Auction)

You're welcome :)

PSIO will be soon... :P
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

AmiDog
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Sep 07, 2012

Post by AmiDog » May 12th, 2014, 6:22 pm

@Tommy

Hmm, I'm trying to understand your problem, but seem to fail miserably :)

What exactly doesn't work as you expect?

Interlace mode of the PSX is nothing special. It will alternate between displaying odd and even lines from VRAM, i.e., line 0,2,4,6,8... for one field and 1,3,5,7,9... for the other. You don't need to do anything but enabling interlace mode (i.e. set interlace and height bit, both need to be set). During the active area (outside VSYNC) the most significant bit of the GPU status can be used to tell which rows (odd or even) are currently being displayed. There's also a field-bit in the GPU status register, which interestingly enough is set to the opposite of the odd/even bit...

Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Post by Tommy » May 13th, 2014, 1:14 am

AmiDog wrote:@Tommy

Hmm, I'm trying to understand your problem, but seem to fail miserably :)

What exactly doesn't work as you expect?

Interlace mode of the PSX is nothing special. It will alternate between displaying odd and even lines from VRAM,
It will also alternate between drawing odd and even lines to the frame buffer — if even lines are outgoing then any geometry you plot will update only odd lines of video RAM.

As I stated clearly, my fields are strictly sequential. Logic updates 50 times a second. Every field is rendered at a different point in game time.

Therefore if No$PSX were implemented accurately and my code were correct, if you pause the emulation and inspect video memory you'd expect to see a weave effect. Odd scan lines will be one frame, evens another.

You do not see that.

Furthermore, the ODE flag is incorrect during vsync for odd fields. I have the prescribed fix in code but disabling it makes no difference. With it disabled, I draw a single triangle, always during vsync. If No$PSX and my code were correct then you'd therefore expect me never to render anything other than even lines. Every odd frame should be blank. The triangle should flicker on and off. It doesn't.

Shadow's test of the code (with ODE fix in place) appears to put the ball in No$'s court; hopefully nocash will spot this thread and comment.
Shadow wrote:(i) You can get a USB AV capture card for ~$10 on eBay. I use VLC to stream the video.
(ii) Applies to (i).
(iii) You use a FTDI (the FTDI-RL is prefered) USB Serial Adapter.
Having looked around, I've got a US$9 adaptor coming from Amazon which appears to be well supported by third-party software as the data sheets are available. Also the author of one piece claims only 1–3 frames latency so it may even be usable for playing games.

I think I've learnt that PSXDEV expects me to open up and solder things into a PlayStation? As a clumsy man with giant hands that would make its cost approach an infinite amount as I'd break pretty much any device I opened.

I'll try to buy a modded slim, whether PS2 or PS1 as those use external power supplies and are therefore not a wasted cost when I move back home. When PSIO comes out I can buy a full-size device too since, unmodded, they're a negligible price, and I'll have a much better idea of where I expect to live in the medium term by then so I'll be able to buy the right one.

That'll move me from not being able to test on real hardware to being able to test on real hardware. Not as good as being able routinely and easily to test but much better a position than now. My code is being written to target both the PlayStation and my native machine because that buys me a step debugger and a modern IDE (e.g. errors highlighted as soon as I type them); I therefore wouldn't expect every build cycle to go to the PlayStation no matter what setup I had.

Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Post by Tommy » May 13th, 2014, 2:13 pm

AmiDog: in case it helps you understand what we're talking about, see the attached .zip.

(aside: it's now a rotating quad that you walk around, with poor arithmetic precision, no conscious attempt at clipping, and probably with very poor timing; use X + pad to strafe)

WithODEFix.exe works as Sony would advocate. It catches vsync, checks whether ODE has changed since the last entry into vsync and, if not, waits until it changes. So when the ODE flag is zero and should be zero it starts drawing immediately. When the ODE flag is zero but should be one, it waits until it actually is one and then starts drawing. Half the fields draw in vsync, half draw straight afterwards.

The imaginatively titled WithoutODEFix.exe pretends that Sony fixed the ODE bug before shipping. It does all drawing immediately upon entry into vsync — one framebuffer wipe and two triangles. So, realistically, it does all drawing during vsync.

So, if you assume my code is correct, the former should display correctly. The latter should display only alternate fields correctly as it'll always draw to the same field.

On No$PSX both display identically.

(EDIT: also this seems like it may be the solution to my serial cable problem)
You do not have the required permissions to view the files attached to this post.

AmiDog
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Sep 07, 2012

Post by AmiDog » May 14th, 2014, 8:12 pm

Tommy wrote:It will also alternate between drawing odd and even lines to the frame buffer — if even lines are outgoing then any geometry you plot will update only odd lines of video RAM.
Very interesting. Didn't know that! Googling "PSX GetODE" did turn up an interesting PDF :)

I wrote some test code, ran it on my SCPH 7002 unit, and had a look at the resulting VRAM dumps. Looks like the PS1 uses the odd/even bit in the status to decide which rows to render to, and that bit is only valid during the active area of the display (i.e. outside VSYNC area) as I learned some week ago while messing with the root counters.

AmiDog
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Sep 07, 2012

Post by AmiDog » May 14th, 2014, 9:53 pm

Tommy wrote:AmiDog: in case it helps you understand what we're talking about, see the attached .zip.
Based on the result from the tests I made, I've implemented the PS1 behavior in my slow-as-*bleep* WIP PS1 emulator. Result:

WithODEFix
Image

WithoutODEFix
Image

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 548
Joined: Nov 12, 2012
Contact:

Post by nocash » May 19th, 2014, 9:28 am

Tommy wrote:It will also alternate between drawing odd and even lines to the frame buffer — if even lines are outgoing then any geometry you plot will update only odd lines of video RAM.
Interesting, I didn't knew that either! I always thought it would render all lines, so that (if you have only space for one framebuffer) rendering time would be restricted to the vblank period, which would make it almost impossible to use animated hires graphics.
But with that even/odd rendering feature things are looking much better: The hardware needs to draw only half as much pixels, and rendering can be done throughout one whole 50hz frame, allowing to use both drawing & vblank periods. Very good to know that!

What exactly is an "ODE flag"? Is that some software/library thing, that tells the game to render each scene twice, for even & odd lines? Or is it some hardware flag?

Hardware-wise, I would assume that the even/odd rendering feature gets enabled when setting Bit2 (vertical resolution) in the GP1(08h) - Display mode register?
And/or... Bit5 (interlace) in the same register might be also related.

And Bit31 of GPUSTAT (even/odd line) should be also relevant for choosing which lines to render to - the bit seems to be always 0 during vblank though (at least in noninterlaced mode).
Is there anything know when the rendering destination gets changed... on begin/end of vblank?
Or is there some way to manually select even/odd lines as destination?

I've checked the three .EXE files on hardware (using upload via parallel port, so results might be slightly different as than booting from cdrom).

MAIN.EXE looks quite same as in no$psx. There's one tiny glitch on hardware: Video mode is 224 lines/NTSC. But, the frame buffer is 240-lines. That's a bit too much for my TV set (picture gets enabled during vertical flyback, causing some diagonal dirt line appearing at the top of the screen).
Basically using more than 224 lines on NTSC for "overscan" pictures is a good thing (ensures that you won't get black screen borders on differently calibrated TVs). But to avoid the dirt line effect, it may be more recommended to use something like 236 lines instead of 240 lines) (and of course if you do HAVE black borders (=as in your frame buffer) then you could as well use plain 224 lines size).

WithoutODEFix.EXE seems to render only even or only odd lines. The other lines are uninitialized (showing relicts of the BIOS GUI in left half, and completely uninialized VRAM in right half) - that's looking a bit dirty - but, it's also prooving that the hardware is really updating only half of VRAM.

WithODEFix.EXE doesn't work for me. I am only seeing a black screen on hardware.
(Or... almost black: It does show the diagonal line from the vertical flyback glitch).

I'll try to emulate the half-rendering stuff in next 1-2 updates. The nice thing about rendering only one half of memory is that it should make the emulation twice as fast in interlace mode.

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 548
Joined: Nov 12, 2012
Contact:

Post by nocash » May 19th, 2014, 9:45 am

AmiDog wrote:I wrote some test code, ran it on my SCPH 7002 unit, and had a look at the resulting VRAM dumps. Looks like the PS1 uses the odd/even bit in the status to decide which rows to render to, and that bit is only valid during the active area of the display.
Oops. You mean, during vsync (...AND vblank?), the hardware is always using the SAME lines as target? Not switching between even/odd target lines? So rendering during vblank won't work. That would be bad. Ironically, then a bigger frame buffer with unused dummy overscan lines would increase the available rendering time.

Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Post by Tommy » May 19th, 2014, 10:31 am

nocash wrote:Oops. You mean, during vsync (...AND vblank?), the hardware is always using the SAME lines as target? Not switching between even/odd target lines? So rendering during vblank won't work. That would be bad.
Well, per the documentation the flag always has the same, predictable value during retrace. So it's correct every other field. You need to sit out half the retraces, not all of them. Or, I guess ideally, enable whichever timer it is that allows you to catch hsync if you enter vsync but spot that the flag is wrong, then get moving again from an hsync interrupt and cancel that timer once the flag flips. My very approximate use of terminology stemming from the fact that I've read the software documentation but still don't have any real hardware — though I have it all ordered now so things are progressing.

Re: my code not working with the ODE fix in place and doing two triangles rather than one, I have no immediate guesses. As you'd imagine, I have the ordering tables queued up for display and the interrupt routine does no more than spit them out. That stuff didn't change between main.exe and WithODEFix.exe. All calculation occurs during normal CPU progression, completely asynchronously so it's not like some extra overhead is affecting that timing (at least in any meaningful, reliable sense).

And, yeah, it's currently meant to be PAL only. I need to fix that. I am aware that in older TVs the two syncs and the electron guns are independent circuits.

AmiDog
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Sep 07, 2012

Post by AmiDog » May 19th, 2014, 6:36 pm

nocash wrote:And Bit31 of GPUSTAT (even/odd line) should be also relevant for choosing which lines to render to - the bit seems to be always 0 during vblank though (at least in noninterlaced mode).
Is there anything know when the rendering destination gets changed... on begin/end of vblank?
Or is there some way to manually select even/odd lines as destination?
What my testprogram does is to wait for vsync and even field (see bit 13 of GPUSTAT, it's set in non-interlace mode which always shows the same field, and changes each field in interlace mode). Using the rasterline counter, the program than waits a number of raster lines, renders a 256x256 pixel rectangle, and dumps the resulting output. That way I was able to verify when and how the GPU decides if it should render odd or even lines, which turned out to be in sync with GPUSTAT bit31 (but the opposite ofcourse).

According to my findings (7002 unit), bit31 is set to the least significant bit of the vertical VRAM display offset during vblank in both non-interlaced and interlaced mode. Rendering destination seems to change when bit31 changes, which it normally does at the start and end of vblank in interlace mode. Also, it seems that a change of bit31 during rendering of a primitive doesn't affect if odd or even lines are being drawn (rendering a 256x256 rectangle, even when only rendering every other row, should take some 4 rasterlines, but I didn't observe any mid-render changes).

I haven't verified it, but theoretically, if the above holds, it should be possible to set the display offset during vblank to force the GPU to render odd or even rows, as long as one makes sure to finish rendering before vblank ends. I assume it could be used to render a background or similar which always take the same amount of time, and then restore the display offset, wait for the end of vblank, and then continue rendering when bit31 has got the desired value. Would save a lot of cycles compared to simply waiting for the end of vblank before rendering anything...

AmiDog
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Sep 07, 2012

Post by AmiDog » May 20th, 2014, 11:16 pm

I can confirm that it's indeed possible to force the GPU to render odd or even rows during vblank. However, changes to the display offset doesn't have any affect until bit31 changes, which it does once per rasterline, so one better busy-wait until it has changed to the desired state, or one will end up rendering to the wrong rows...

Tommy
Active PSXDEV User
Active PSXDEV User
Posts: 48
Joined: Apr 19, 2014

Post by Tommy » May 25th, 2014, 1:54 pm

Although the topic has strayed into much more interesting territory in the interim, I just thought I'd mention that I've managed to try the latest version of my code on real hardware at last and all works well. I threw what I had into the Codeblast competition because at the time there were no other entries and at least it would be something. As a result you can find updated builds, see some shots and view a real-hardware video in that thread. I don't see any benefit to regurgitating that stuff here.

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 548
Joined: Nov 12, 2012
Contact:

Post by nocash » May 27th, 2014, 8:17 am

AmiDog wrote:What my testprogram does is to wait for vsync and even field (see bit 13 of GPUSTAT, it's set in non-interlace mode which always shows the same field, and changes each field in interlace mode).
I didn't knew about bit13 (and thought it would be unused/reserved/always 1).
Very good to know about that detail, too. Many thanks!

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests