Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 8 commits into from
Jul 7, 2024

Conversation

sergiopolog
Copy link
Contributor

@sergiopolog sergiopolog commented Jun 29, 2024

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.

  • "Horizontal" signals, such as HBlank, HSync... are generated using one of the counters and a 256x4bit PROM, and each step on the counter takes 2 pixel clock cycles.
    • For "low-res" games the counter starts on 0x40 and goes to 0xFF having 192 steps. As each step is 2 px, so the total H-size is 384px wide. PROM entries from 0x00 to 0x39 address are never used.
    • For "hi-res" games the counter starts on 0x00 and goes to 0xFF having 256 steps. As each step is 2 px, the total H-size is 512px wide. All PROM entries are used.
  • "Vertical" signals, such as VBlank, Interrupt requests... are generated using the other counter and a 256x8bit PROM, and each step on the counter takes 2 scanlines.
    • In this case, for all games the counter starts on 0x75 and goes to 0xFF having 139 steps. As each step is 2 lines, the total V-size is 278 lines high. PROM entries from 0x00 address to 0x74 are never used.

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:

  • For "low-res" (6MHz pixel clock):
                         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

  • For "hi-res" (8MHz pixel clock):
                         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:

  • removed from: macross2, tdragon2, sabotenb, bjtwin, nouryoku, ssmissin, airattck and clones of all them
  • added to: tharrier, stagger1, grdnstrm, and clones

* removed from: `macross2`, `tdragon2`, `sabotenb`, `bjtwin`, `nouryoku`, and clones of all them
* added to: `tharrier`, `bioship`, `vandyke`, and clones
…KTAIL` flag on afega and nmk16 games:

* removed from: `ssmissin`, `airattck`, and clones of all them
* added to: `stagger1`, `grdnstrm`, and clones
…fix flipscreen on 'bioship` and `vandyke`
@mamehaze
Copy link
Contributor

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

@sergiopolog
Copy link
Contributor Author

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
Copy link
Contributor

rb6502 commented Jun 29, 2024

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
Copy link
Contributor Author

@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
Copy link
Contributor

rb6502 commented Jun 30, 2024

Thanks, looking forward to it!

src/mame/nmk/nmk16.cpp Outdated Show resolved Hide resolved
src/mame/nmk/nmk16.cpp Outdated Show resolved Hide resolved
@sergiopolog sergiopolog changed the title nmk16.cpp: Adjusted values for proper screen size, timings and interrupts, according to real hw nmk/nmk16.cpp: Adjusted values for proper screen size, timings and interrupts, according to real hw Jul 4, 2024
@rb6502 rb6502 merged commit 767957e into mamedev:master Jul 7, 2024
5 checks passed
@sergiopolog sergiopolog deleted the nmk16_timing branch July 7, 2024 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants