Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - [FIXED] SMS-only VDP issue (works on MD/Genesis)

Reply to topic
Author Message
  • Joined: 23 Aug 2009
  • Posts: 213
  • Location: Seattle, WA
Reply with quote
[FIXED] SMS-only VDP issue (works on MD/Genesis)
Post Posted: Thu Nov 14, 2019 6:13 pm
Last edited by SavagePencil on Thu Nov 14, 2019 7:53 pm; edited 2 times in total
I'm trying to figure out why something I've written works on a Genesis but doesn't on an actual SMS1. I can reproduce the issue in Emulicious by toggling the "Emulate VDP Constraints" option, but I don't know exactly which constraint I'm violating.

It appears to be an issue with VRAM. I'm either writing to it too fast or I have a register set incorrectly, causing the nametable to behave improperly. Graphics are shifted improperly.

When writing to VRAM, I believe I am in the following state:
*
di

* Frame Interrupt is set to OFF on Register $01
* Display is set to OFF on Register $01

I *believe* I have Register $03 set correctly to $FF, but I'm not sure how to see the VDP regs in Emulicious.

Sometimes things stay in the nametable after they are supposed to be cleared. For example, sometimes a character from the title screen will linger when going to the round intro screen, even though I've called the ClearNameTable routine.


ClearNameTable:
    ld  hl, VDP_NAMETABLE_START_LOC
    SET_VRAM_WRITE_LOC_FROM_HL
 
    ; Now clear all of VRAM for the nametable.   
    ; Each write to the data port increments the address.
    xor     a
    ld      bc, VDP_NAMETABLE_SIZE >> 8
-:
        out     (VDP_DATA_PORT), a
        djnz    -
    dec     c
    jr      nz, -
    ret


I have confirmed that the bad state repros when run on a real SMS and that it looks fine on an actual Genesis.

I'll attach the "with limitations on" and "with limitations off" images. Ignore the "A" character, that's a sprite :)
spies-1.png (811 B)
Looks correct. Limitations OFF.
spies-1.png
spies.png (960 B)
Looks incorrect. Limitations ON.
spies.png

  View user's profile Send private message
  • Joined: 28 Feb 2016
  • Posts: 503
  • Location: Barcelona
Reply with quote
Post Posted: Thu Nov 14, 2019 6:26 pm
This is clear a VDP limit error

Try something like:

-:
nop
nop
out (VDP_DATA_PORT), a
nop
nop
djnz -

Until process is corrected.
  View user's profile Send private message
  • Joined: 23 Aug 2009
  • Posts: 213
  • Location: Seattle, WA
Reply with quote
Post Posted: Thu Nov 14, 2019 7:14 pm
...but is that necessary when Active Display is off?

I think I've found the problem: I'm not actually in Active Display off.

and     ~(VDP_REGISTER1_ENABLE_DISPLAY | VDP_REGISTER1_ENABLE_VBLANK)


Does not "NOT" those OR'd values, as I would expect. It just...lets them be, I guess, because the assembler turns that into:

and $60


...when I would expect it to be:

and $9F


I think I can get the correct thing emitted by making it:

and     $FF ~(VDP_REGISTER1_ENABLE_DISPLAY | VDP_REGISTER1_ENABLE_VBLANK)


...but will have to try that when I get home. I'm still interested if Emulicious can show me the state of the VDP registers.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Thu Nov 14, 2019 7:55 pm
It works on a Mega Drive because it has a FIFO buffer on the VDP to help in this situation.

Depending on your assembler, ~ might mean “not” or “XOR” - I guess here it treated it as 0 XOR $9f = $9f, adding the $ff on the left got the result you wanted. I guess this is WLA DX - so maybe raise an issue that it ought to have rejected a unary ~ operator.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Aug 2009
  • Posts: 213
  • Location: Seattle, WA
Reply with quote
Post Posted: Thu Nov 14, 2019 9:21 pm
That all makes sense. I'll file a bug on WLA-DX. Really, I'd prefer if they allowed a unary ~ instead of XOR.

(fun fact: the problem did NOT appear on MEKA)

Follow-up Qs:
1. Is there a way to see the VDP regs from within Emulicious?
2. Are there any timing constraints necessary when active display is off? Or is a tight loop like above going to work reliably without adding any NOPs?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Thu Nov 14, 2019 10:48 pm
Last edited by Maxim on Fri Nov 15, 2019 9:32 am; edited 1 time in total
When the display is off the Z80 cannot access the VDP fast enough to cause problems.

Meka does not emulate timing constraints. I’m pretty sure no game depends on them.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Nov 15, 2019 8:49 am
SavagePencil wrote
Are there any timing constraints necessary when active display is off? Or is a tight loop like above going to work reliably without adding any NOPs?


you can write to VRAM as fast as you can when display is off (or during vblank)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Dec 2019
  • Posts: 56
  • Location: USA
Reply with quote
Post Posted: Sun Dec 22, 2019 11:51 pm
I've seen conflicting info about the VDP's rate limit outside vertical or forced blanking: one write every 26, 29, or 32 Z80 cycles. Is there an authoritative document about the VDP's cycle-by-cycle VRAM access pattern the way there is about the NES PPU? (See "PPU rendering" on NESdev Wiki)

There's "Genesis Mode 4 VRAM Timing" on this forum implying that the VDP never uses more than 15 slots in a row, which would mean at least one "external slot" every 16 slots or 32 pixels. It's for Genesis mode 4, but a reply implies that SMS2 mode 4 has the same timing. That sort of implies 22 Z80 cycles as the minimum spacing.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Dec 23, 2019 10:19 am
Official documents, AFAIK, state that the required cycles are 29.
Extensive testing shows that everything still works as long as the minimum cycles are at least 26.
Genesis has a FIFO, SMS has no such thing.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!