Turns out the source of a LOT of game bugs was that I was following the Z80 documented undocumented document where it was saying that DD/FD are treated as "separate instructions that set an internal flag", hence you can easily stack multiple prefixes like DD DD FD DD FD CB ... and it'll "ignore" all but the final FD.

But if I do this, and allow interrupts to fire between the prefix and CB opcode, obviously very bad things happen.

So ... what happens in a sequence like the above? What if I fill the bus with nothing but 0xDD? (All ROM and all RAM.) Will IRQs and NMIs never fire as a result?

Interrupts aren't processed after a prefix, including redundant prefixes. As you've noticed, if they did then there would be no way for the CPU to recover. So a sequence of redundant IX/IY prefixes will indeed postpone interrupt processing for arbitrarily long. I think x86 CPUs up to the 80186 or so are the same with segment prefixes (didn't you have to deal with this when emulating the WonderSwan?) Starting with the 286, x86 CPUs started enforcing a maximum single instruction length and throwing an exception if it's exceeded, precisely so that software can't lock up the CPU by jumping into a code segment entirely filled with prefix opcodes. The limit is 10 bytes on the 286 and 15 bytes on the 386 and everything after.

> Interrupts aren't processed after a prefix, including redundant prefixes. As you've noticed, if they did then there would be no way for the CPU to recover.

Neat! That'll make emulation easier, I can just force the instruction() function to not return until a non-prefix instruction has executed. The cooperative threading will save me if the CPU gets stuck in an infinite loop, although trying to capture a save state would cause a lock up. Probably not worth losing sleep over a situation that'll never actually occur.

> didn't you have to deal with this when emulating the WonderSwan?

Interestingly enough, the V30MZ only guarantees up to seven prefixes in a row to execute correctly. It has an "all bets are off" note if you go beyond that. Of course, not knowing what actually happens, I don't emulate the limitation in any way.

More fun for me, just finished a HuC6280 core. Seems the TAI/TIA/etc instructions also delay interrupts until they complete. And those can transfer a full 64KB of data at a very slow six cycles per byte. I think those are officially the longest-to-execute instructions I've implemented yet.

^ Sure. But if you want to write to vram during active display with Txx instructions, you have to use smaller segments like 32 bytes as not to delay hsync interrupts too long (all writes to vdc regs are buffered, but you have a 455 cpu cycle window to get them written per line). That brings down the transfer rate to vram at 7.5 cycles per byte during active display (all VDC reg access have +1 cycle penalty to read/write instructions), and 6.5 cycles for non VDC/VCE areas of memory.

If you embedded graphics as ST1/ST2 opcodes, its 5 cycles a byte to vram and is interruptible.

Yes it's the bit 2 of the VDC status(if HSYNC interrupt is not disabled ,bit 2 of VDC register $5) .You can set the line you want to have an interrupt with the VDC register $6 and you must add 64 to your line for the proprer VDC line interrupt(because the VDC start to draw the screen at line 64 and not 0) .Of course you can set multiple line interrupt in a single frame(but one line at a time) .

Quote:

Just a guess, but perhaps tomaitheous was referring to line coincidence

When I think hsync, I think something like SNES HDMA, where the goal is to fire during the horizontal blanking period of each line so you can write to registers before the next active display section.

> (because the VDC start to draw the screen at line 64 and not 0)

That really doesn't make sense, either. I know to do the -64 thing when comparing against the actual scanline number, but still ...

If we really started on scanline 64, then we couldn't have 240-pixel height screens when there are only 262 or 263 scanlines per frame. 240+64=304.

It seems like the "we start at line 64" is just a hack to make the sprite clipping on the edges of the screen a little bit easier to handle (and that is certainly appreciated.)

> Of course you can set multiple line interrupt in a single frame(but one line at a time) .

Yes, but the critical detail is that it fires at the end of the rendering portion of the scanline, and line coincidence doesn't do that. It fires right at the start.

And if the PCE documentation is to be believed (and I don't fully believe it), it seems to suggest the PCE caches a lot of registers at the beginning of each frame, which makes raster effects kind of hopeless. All I'll say is the H/V timing (start/end/width/height/etc) goddamned better be cached once per frame :P I've never emulated a system that has the equivalent of setting your own Xorg modelines before. That's going to be quite the treat.

But ... I don't know. Something's still fundamentally and horribly broken somewhere in my HuC6280 CPU core. Having quite a bit of trouble finding it, due to a dearth of test ROMs.

When I think hsync, I think something like SNES HDMA, where the goal is to fire during the horizontal blanking period of each line so you can write to registers before the next active display section.

Huh? Hsync.. when the sync pulse starts for the horizontal line (raising edge/end of pulse) -> if the line number matches the RCR reg, an interrupt is generated. Aka hsync interrupt. What else would it be??? The VDC generates this, not the VCE. The VCE might sync the VDC, but the VDC itself can be set to have multiple hsync interrupts triggered per line (VCE line/frame work).

Anyway, that's what it does. Fires during hsync so the cpu can update regs before the next scanline. The regs are buffered, so you can take as long as you need to write to them. Registers that affect the hozirontal display settings are updated on the next line (X/Y/width/offset/etc), and regs that affect the vertical display setting are updated on the next VDC "frame" (not necessarily per "VCE" frame).

Quote:

> (because the VDC start to draw the screen at line 64 and not 0)

That really doesn't make sense, either. I know to do the -64 thing when comparing against the actual scanline number, but still ...

If we really started on scanline 64, then we couldn't have 240-pixel height screens when there are only 262 or 263 scanlines per frame. 240+64=304.

It seems like the "we start at line 64" is just a hack to make the sprite clipping on the edges of the screen a little bit easier to handle (and that is certainly appreciated.)

64 is not the 64th scanline. It's the first visible scanline (however that is defined). Hsync interrupt can fire on any scanline, including those outside of active display (this is used to playback 15.7khz samples for demos).

Quote:

And if the PCE documentation is to be believed (and I don't fully believe it), it seems to suggest the PCE caches a lot of registers at the beginning of each frame, which makes raster effects kind of hopeless.

Raster effects outside of X,Y,(2bit/4bit color more for sprites or BG), sprites on/off, bg on/off, etc? Those are buffered per VDC line. The changes take place on the next "VDC" line. What other raster effects do you need? I say VDC line, because it's possible to have more than one VDC line inside of a VCE line. This should be obvious, because if the VDC is in h-pulse window mode, it's waiting for VCE to snap it to the next mode. If the VCE doesn't, then the VDC times out and continues on the next mode/phase by itself. But if the VCE asserts hysnc, it doesn't matter were the VDC is.. it will immediately snap to the phase that follows hsync pulse window (I forgot the official names of these).

VCE reg changes aren't like VDC reg changes. They take place immediately, including changing the resolution (can be done mid scanline).

64 is not the 64th scanline. It's the first visible scanline (however that is defined).

Fortunately tomaitheous explained it with more details .

Quote:

I've never emulated a system that has the equivalent of setting your own Xorg modelines before.

yes i agree, it's a little bit confusing, but permit a large screen configurations like wide screen/letter box without any tricks .The cool thing is with the SGX, you can configure each VDC with your own set of screen parameters .

Nope, I'm done writing new emulator cores now. I may emulate add-ons, but this was my last from-scratch emulator.

> The cool thing is with the SGX, you can configure each VDC with your own set of screen parameters .

That is very much not cool D:

I'm going to have to internally stretch the video (interpolate) from both chips in order to combine them now.

> Huh? Hsync.. when the sync pulse starts for the horizontal line (raising edge/end of pulse)

Sync is the time when the screen is not rendering. That usually comes at the end, not the beginning.

When we say Vsync on the SNES, we're talking about the last 38 scanlines when you can write to VRAM, etc.

Hsync naturally extends to "the time -after- the scanline rendered, before the next one starts, when you can write to registers safely."

> What else would it be???

A line coincidence interrupt.

> regs that affect the vertical display setting are updated on the next VDC "frame"

And apparently if you write to the vertical register it takes immediate effect. However, the Y position isn't screen Y + scroll Y, but rather the latched copy of scroll Y is incremented once per scanline.

Neutopia absolutely requires this. And if not for Ryphecha's help on this, it would've taken me ages to figure that out >_>

> So no plans for b5150 in higan, I take it :pI'm going to have to internally stretch the video (interpolate) from both chips in order to combine them now.

The VCE controls the dot clock for both at the same time, not individually. I don't see the problem in mixing the two signals, although VPC regs (the mixer) can be changed per scan line (buffered per line like VDC IIRC) - window mixing regs.

Quote:

Sync is the time when the screen is not rendering. That usually comes at the end, not the beginning.

It's a matter of perspective. The raising edge of the hsync is arguably the beginning of the next line, in which the VDC generates the interrupt (if line match). It's more natural to call it hsync interrupt, regardless of the matching mechanism for the trigger. Hudson never officially called it "Line coincidence" interrupt; the official docs refer to it hsync or horizontal interrupt. I've only ever seen "LC" terminology from Nintendo (gameboy).

Quote:

> regs that affect the vertical display setting are updated on the next VDC "frame"

And apparently if you write to the vertical register it takes immediate effect. However, the Y position isn't screen Y + scroll Y, but rather the latched copy of scroll Y is incremented once per scanline.

Neutopia absolutely requires this. And if not for Ryphecha's help on this, it would've taken me ages to figure that out >_>

VCE also control the resolution for the VDC (dot clock), the 263/262 scanline mode, as well as the color burst signal (B&W). It also has its own unique pixel distortion during active display.

I have no idea how accurate you plan to go with this, but the VDC processes BG and sprite line setup at different 8pixel dot clock segments during hblank. It's possible to have the VDC draw out the BG tiles as 8 pixels tall, and have it skip other every line of sprites (effectively showing 16 pixel tall cells as 8 pixel tall). Mednafen comes close (4px tall tile cells, 8px tall sprite cells), but it doesn't handle this above case scenario.

> It's a matter of perspective. The raising edge of the hsync is arguably the beginning of the next line, in which the VDC generates the interrupt (if line match).

After talking with Ryphecha about it, she advised that the interrupt actually triggers near the very end of the previous scanline you asked for. Which would indeed be the Hblank area, and give games times to do things to affect the line they were targeting.

> Which VDC reg?

BYR. And I just found there's a THIRD level of latching to it. The cached BYR value is latched at the start of the scanline. Without that, you'll get momentary flicker when games write the register mid-scanline. Which they do a lot because there's only one background and no windows.

> I have no idea how accurate you plan to go with this, but the VDC processes BG and sprite line setup at different 8pixel dot clock segments during hblank.

I am limited by the available information. And the available information is unbelievably awful and outdated from 2007 and earlier =(

But I want to be as accurate as possible. I just emulated the display start, display length regs. But not yet the display end, sync width regs. Nor the "fun" that happens with out of bounds values (you can apparently make the VDC start drawing the NEXT scanline on the current scanline if your values are too aggressive.)

Even with just that, I'm still having troubles. HDS (horizontal display start) seems to act differently depending on the $0400.d0-d1 clock frequency setting (5mhz, 7mhz, 10mhz). Unless I manually fudge the start offset by another ~24 clock cycles for 7mhz mode only, the status bar in Order of the Griffon isn't centered.

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum