mamedev / mame

MAME
https://www.mamedev.org/
Other
7.76k stars 1.95k forks source link

nmk/nmk16.cpp: Adjusted values for proper screen size, timings and interrupts, according to real hw #12529

Open sergiopolog opened 5 days ago

sergiopolog commented 5 days ago

Fixed screen size, interrupts and raster timings on nmk16 driver to be more accurate with original hw.

This hardware relies on two counters and the contents of two PROMs for the timing signals generation. The counters are implemented inside NMK-902 custom chip (except tharrier) for all "low-res" games and are used to address the entries on each PROM in a sequential way. On "hi-res" games, one of the counters is implement outside the custom chip, due to they decided to boost up the horizontal resolution.

Going into more detail:

The H-timing PROMs is a 82S129 (256x4bit) (first 64 entries are not used in "low-res") and the format is:

    Offset  Bits     Description
            3210
    0       ---x     Line counter trigger (active low)
    1       --x-     HSYNC (active low)
    2       -x--     HBLANK (active low)
    3       x---     unused on almost all games (only used in gunnail and raphero, purpose unknown)

Considering that and looking at the contents of the PROM, the horizontal timings are below:

                         0.....31.........91.....................................................................348.....366.....383
/LINE-END (2 px):        ----------------------------------------------------------------------------------------------------------X
HSYNC  (32 px):          XXXXXXXX---------------------------------------------------------------------------------------------------
HBLANK (92 + 36 px):     XXXXXXXXXXXXXXXXXXX------------------------------256-wide-------------------------------XXXXXXXXXXXXXXXXXXX  // HBlank ends 92 pixels after 'start of line'
                         ^
                         |
                 'start of line'  (pixel 0)

Each line: ( 6MHz / 384 pixels per line ) = 15625Hz = 64 usec

                         0...27............................................................................412...432...448.479...511
/LINE-END (2 px):        ----------------------------------------------------------------------------------------------------------X
HSYNC  (32 px):          ----------------------------------------------------------------------------------------------XXXXXXX------
HBLANK (28 + 100 px):    XXXXXX-------------------------------------------384-wide-------------------------XXXXXXXXXXXXXXXXXXXXXXXXX  // HBlank ends 28 pixels after 'start of line'
                         ^
                         |
                 'start of line'  (pixel 0)

Each line: ( 8MHz / 512 pixels per line ) = 15625Hz = 64 usec

For V-timing PROM, it's a 82S135 (256x8bit) (first 117 entries are not used) and the format is:

    Offset  Bits         Description
            76543210
    0       -------x     Sprite DMA trigger (active low)
    1       ------x-     VSYNC (active low)
    2       -----x--     VBLANK (active low)
    3       ----x---     unused
    4       ---x----     IRQ1 (active high)
    5       --x-----     IRQ2 (active high)
    6       -x------     IRQ4 (active high)
    7       x-------     Interrupt Trigger (active low and effective on the very next PROM entry (2 scanlines), the interrupt is triggered on 0 to 1 transition)

Considering that and looking at the content of the PROM, the vertical timings are below:

                         0.8.13..22.37.....................................................................................262...277
/SPR-DMA-START (2 lines):--------------------------------------------------------------------------------------------------X--------
VSYNC  (6 lines):        --XXXX-----------------------------------------------------------------------------------------------------
VBLANK (38 + 16 lines):  XXXXXXXXXXXXX------------------------------------224-high-----------------------------------------XXXXXXXXX  // VBlank ends 16 lines after 'start of frame'

                         0.9...21.....38..53......90..103..................................................218.231.........262...277
IRQ1 (15 + 15 lines):    -------------------------XXXXXXX-----------------128-gap--------------------------XXXXXXX------------------  // some games like bioship and vandyke have this interrupt a bit shifted, will be fixed in the next PR
IRQ2 (16 lines):         -------------XXXXXX----------------------------------------------------------------------------------------  // sometimes not present, i.e. tdragon2, macross2...
IRQ4 (26 lines):         XXX-----------------------------------------------------------------------------------------------XXXXXXXXX
/FRAME-END (22 lines):   XXXXXXXX---------------------------------------------------------------------------------------------------  // This signal is low on last 22 lines of each frame and goes high on the first line of the next one
                                 ^
                                 |
                         'start of frame'  (line 22)

VBLANK time: ( 6MHz / 384 pixels per line ) / 54 lines per VBlank = 289.35185185Hz = 3456 usec Active video time: ( 6MHz / 384 pixels per line ) / 224 lines per Active = 69.75446428Hz = 14336 usec Time between IRQ1: ( 6MHz / 384 pixels per line ) / 128 lines between IRQ1s = 122.0703125Hz = 8192 usec

Given that, the screen size, HBlank and VBlank are adjusted on each case. Interrupts and video offsets are also fixed to their proper positions.

On a later Pull-Request I'll submit new code for triggering interrupts based on the actual contents on the V-timing PROM, in order to trigger the interrupts dynamically and allowing each game trigger them by its own, instead of hardcoding them on the code. It's known that IRQ1 in 'bioship' and 'vandyke` is a bit shifted compared to other games, and some hi-res games don't use IRQ2.

No clue how they implemented it on Afega games hw, but they work in the same way.

Additionally, flip-screen is fixed for vandyke, bioship and clones. Contrary to rest of games, vandyke writes a 1 instead of 0 when flip-screen is required, so a new adapter handler is added for that special case.

Adjusted MACHINE_NO_COCKTAIL flag on:

mamehaze commented 5 days ago

I think the information on the PROM use should go in the driver so it doesn't get lost here?

sergiopolog commented 5 days ago

I think the information on the PROM use should go in the driver so it doesn't get lost here?

@mamehaze what would be the best place to put that info? On the driver header, maybe? I could paste all the text above on there, if that's fine

rb6502 commented 5 days ago

Hi @sergiopolog. I like Haze, but he's not a member of the team so his suggestions are not rules.

Our preference would be for MAME to use the actual PROM data live, so that changing the contents of the PROM would alter the video parameters. That would be great for people who want to make their own games on these boards, and it would work more like hardware.

The code scanning the PROMs to compute the parameters would then be an excellent place to put those comments.

sergiopolog commented 4 days ago

@rb6502 ok, then I will include all the above as complementary info on the code I will submit in my next PR, including the code to use the actual data from PROM to trigger interrupts

rb6502 commented 4 days ago

Thanks, looking forward to it!