User avatar
chupo_cro
Posts: 4
Joined: Thu Jun 29, 2017 2:08 am
Location: Hrvatska

VBLANK and interrupt? (debugging my own code for Pac-Man HW)

Hi all,

my first post here.

For quite a long time I've had an idea of making a game that would run on an original arcade hardware and I finally started to write the code for Pac-Man hardware. I've set up a toolchain using SjASMPlus so I can compile the test code and produce pacman.6e ROM file for pacman.zip ROM set in seconds and that works well. I already did initializing, print string (to both central and top/bottom area and in both horizontal and vertical direction), print hex, read joystick, scroll sprite, ... routines and I set up the interrupt (IM 1) routine to update the tick counter, move the sprites, read the input etc. I am not modifying existing ROM files, I am creating the ROM files from scratch by compiling the code I write in assembly.

Everything until now worked as expected until I noticed sprite scrolling is a bit choppy - looking as the moving speed is not 100% constant at every moment. Since I am updating the sprite coords inside interrupt routine and changing the coords 1 pixel at a time - the moving speed of the sprites should be perfectly steady.

I then used MAME debugger trying to figure out the reason for the imperfection in sprite movements. My interrupt routine being too long to fit between two interrupt requests was out of question because there should be 50684.7 T-states between the two interrupts (Z80 @ 3.072 MHz, screen refresh @ 60.61 Hz) and my interrupt routine needed only about 200 T-states (it now needs about 570 T-states but that is still just about 1% of the available time window). I used the command Run until next VBLANK (F8) and was surprised the interrupt routine is executing on every 2nd VBLANK and not on every VBLANK!?

I thought I do not know something about the Pac-Man hardware so i did't do something that should be done for the hardware to run properly (maybe to output some value on some port or something) so I went to check the interrupts in the original Pac-Man ROMs and the results were exactly the same - the interrupt routine is entered on every second VBLANK impulse and not on every and it can be clearly seen the sprite movement is choppy as well :-/ Pac-Man (Midway) which is pacman.zip is BTW using IM 2 and Pac-Man (bootleg on Namco hardware) which is puckmanb.zip is using IM 1.

I then tried to examine cycles, beamx, beamy and frame valus in MAME debugger trying to find out why the interrupt is not triggered on every VBLANK and I am not sure I understand how cycles and beamy values work. I notice cycles are after each Z80 instrucion decreasing, counting down T-states taken by the instruction. But towards which value are cycles decreasing? Are they decreasing towards the moment when VBLANK signal will be active?

I tried to observe cycles, vblank, beamx and beamy values and I can see beamx goes up to about 380 and then returns back to zero. Visible part of the Pac-Man's screen is 288 px wide so 380 does not correspond to the screen width.

On the other hand, cycles reaches zero when beamy reaches 224 which is the visible height (in pixels) of the Pac-Man's screen - meaning cycles really do count down towards the moment wher VBLANK will be active?! After cycles reaches zero it sometimes jumps to about 7600, sometimes to about 43000, sometimes to about 3060, sometimes to about 39900 so the pattern is not so obvious :-/

So what I would like to know is:

#1
Why is interrupt triggered on every second VBLANK and not on every VBLANK? Does it have something to do with the fact the picture is interlaced so it is drawn in two half-frames? But if the refresh rate is 60.61 Hz then interrupt should be triggered by every VBLANK :-/

#2
Why are cycles in MAME debugger counting towards zero and what is the value the counter jumps to upon reaching zero? How to measure the number of T-states (cycles) between two breakpoints or between two interrupts if the cycles counter in the meantime reaches the zero and then jumps to some value?

I would BTW prefer to use Scramble hardware (because Pac-Man HW doesn't support background scroll, doesn't have 8 way joystick and doesn't have fire/bomb buttons) but couldn't find any documentation. I thought it would be easier to find the Scramble documentation because i read:
Apparently, Scramble's board was especially easy to re-use; several games were hacked to play on it. A long-running joke with MAME enthusiasts is that anything can be run on Scramble hardware - N64 games, your toaster, your automatic garage door, etc. :?) (Ironically, Scramble itself was hacked to play on Galaxian hardware!)

here on the FAQ pages :-/ But the only Scramble HW docs I could find were not even nearly as detailed as the docs I found for Pac-Man HW.

I know I could decipher the hardware info from the MAME driver for Scramble hardware but I am assuming there is some documentation similar to these docs for the Pac-Man hardware.
Chupo_cro
smf
Posts: 4
Joined: Thu Nov 06, 2014 1:34 pm

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

It looks like run to next vblank in the debugger is stopping at the start and end of vblank, which is a bug in the debugger that was introduced last year. I just pushed a fix to github.

I believe the issue you are seeing is more likely to do with frame rate of pacman not being the same as the frame rate of your monitor. You an try running mame with -syncrefresh -waitvsync -nothrottle, which may help but may also cause other issues.

There is also a difference between sprites in real hardware and in mame, which may or may not cause you issues. We currently emulate sprites and tiles in the same coordinate space, but offset a couple of them by a pixel to compensate for some visual issues. I think real hardware they don't actually line up with each other.

beamy & beamx can go higher than the size of "the screen" because it also counts outside the visible area, including hblank and vblank.

The "cycles" in the debugger is how many cycles until the cpu will give up it's time slice. For a single cpu game it's probably counting down to the end of the frame (which is some time after vblank starts). So the first time you pushed f8 it will have some time to go before the end of the frame, when you push it again then the frame will have started and then a short time will have passed by the time vblank finished. The figures might be more useful now that f8 only stops at the beginning of vblank. If a timer occurs then the cpu will also be asked to stop it's timeslice and then start again, which will cause it to change. This would cause you a problem, although I don't know if pacman has any timers that fire. I understand that doesn't completely answer your question, but I'm not sure if there is an answer at the moment.

Scramble became popular among bootleggers because it was easy and cheap to bootleg, they kept at it because it kept making them money. The same reasons that bootleggers these days knock out nes clones. The only reason to switch from pacman to scramble is that scramble boards are cheaper than pacman boards. It may not solve any of the issues you're having, although it might be a greater challenge. Galaxian hardware is also quite common for bootlegs.
User avatar
chupo_cro
Posts: 4
Joined: Thu Jun 29, 2017 2:08 am
Location: Hrvatska

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

smf wrote: Tue Jul 04, 2017 12:21 pm It looks like run to next vblank in the debugger is stopping at the start and end of vblank, which is a bug in the debugger that was introduced last year. I just pushed a fix to github.

So that was the reason. I will then use Run until next interrupt on this CPU (F7) until the bug fix is released in the next stable MAME release.
smf wrote: Tue Jul 04, 2017 12:21 pm I believe the issue you are seeing is more likely to do with frame rate of pacman not being the same as the frame rate of your monitor. You an try running mame with -syncrefresh -waitvsync -nothrottle, which may help but may also cause other issues.

There is also a difference between sprites in real hardware and in mame, which may or may not cause you issues. We currently emulate sprites and tiles in the same coordinate space, but offset a couple of them by a pixel to compensate for some visual issues. I think real hardware they don't actually line up with each other.

Maybe that is what causes choppy sprite movements. Here you are a short (100 KB) video where it can be seen the cherry movement is not uniform. I am not sure if that can be observed only when the video is resized to full screen, it is hard to observe the movement in 244x288. The speed of the cherry sprite is 1 pixel each 2nd interrupt. I made this video using -aviwrite switch, is there maybe a switch to change the rendering resolution of the output video?
smf wrote: Tue Jul 04, 2017 12:21 pm beamy & beamx can go higher than the size of "the screen" because it also counts outside the visible area, including hblank and vblank.

The "cycles" in the debugger is how many cycles until the cpu will give up it's time slice. For a single cpu game it's probably counting down to the end of the frame (which is some time after vblank starts). So the first time you pushed f8 it will have some time to go before the end of the frame, when you push it again then the frame will have started and then a short time will have passed by the time vblank finished. The figures might be more useful now that f8 only stops at the beginning of vblank. If a timer occurs then the cpu will also be asked to stop it's timeslice and then start again, which will cause it to change. This would cause you a problem, although I don't know if pacman has any timers that fire. I understand that doesn't completely answer your question, but I'm not sure if there is an answer at the moment.

It is an excellent debugger but I am missing some features. It would be nice if there would be an option to count cycles upwards and to be able to reset the counter when the program is stopped. That way it would be easy to count T-states between two break points. Such an option is, for example, available in Atmel's AVR Studio 4 debugger, where there are Cycle Counter and Stop Watch counters both which can be reset to zero when the programm is stopped at the breakpoint. There are Reset Cycle Counter and Reset Stop Watch commands and the stop watch can show time in µs or ms.

One more useful feature would be to be able to see the data bus contents at the breakpoint. Thay way it would, for example, be possible to check the lower byte of the interrupt vector address the peripheral hardware has put on the data bus at the time of the interrupt (useful for debugging Z80's interrupt mode 2 but I am sure there are some other usages as well).
smf wrote: Tue Jul 04, 2017 12:21 pm Scramble became popular among bootleggers because it was easy and cheap to bootleg, they kept at it because it kept making them money. The same reasons that bootleggers these days knock out nes clones. The only reason to switch from pacman to scramble is that scramble boards are cheaper than pacman boards. It may not solve any of the issues you're having, although it might be a greater challenge. Galaxian hardware is also quite common for bootlegs.

I would like to use Scramble hardware mainly because Pac-Man hardware doesn't allow to read more than one joystick direction at a time so you can't read up-right and other diagonal directions - and because there isn't hardware scroll of the background tiles so it seems the hardware was used only for the games where the playfield is static.

But the problem is I don't know the pallete, tile and sprite structure of the Scramble's hardware nor I know some other important details which are necessary when writing the code. For example, seems as outputting the value to the port 0 on Pac-Man hardware causes the peripheral hardware to store the byte and put it on the data bus everytime when triggering interrupt. That way the byte from the data bus could be (if IM 2 is enabled) combined with the high byte stored in I register - to form the interrupt service routine addres. One other important information is you can not read the memory mapped locations of the sprite coordinates on Pac-Man hardware - these bytes read always as #FF. On the other hand, Sprite Control memory locations (where there are data about sprite number and x/y flip) can be read. I am missing such and many more important info on Scramble hardware so I can not use it trying to make a game :-/

Thank you very much for the reply and the detailed explanation of inner workings of MAME debugger!!

Best Regards
Attachments
pacman_06 - sprite move.zip
(99.03 KiB) Downloaded 292 times
Chupo_cro
mhoes
Posts: 186
Joined: Wed Oct 26, 2016 12:26 pm

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

chupo_cro wrote: Tue Jul 04, 2017 3:15 pmI made this video using -aviwrite switch, is there maybe a switch to change the rendering resolution of the output video?
Although I haven't verified this myself, the documentation states that you can use "-snapsize <width>x<height>" on the commandline or in your mame.ini to change the size for snapshots and movie recording.

http://docs.mamedev.org/commandline/com ... e-all.html
User avatar
chupo_cro
Posts: 4
Joined: Thu Jun 29, 2017 2:08 am
Location: Hrvatska

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

mhoes wrote: Wed Jul 05, 2017 12:47 pm Although I haven't verified this myself, the documentation states that you can use "-snapsize <width>x<height>" on the commandline or in your mame.ini to change the size for snapshots and movie recording.

http://docs.mamedev.org/commandline/com ... e-all.html

It works, thank you very much!! :-)

This makes 10 seconds video and the screenshot of the very last frame, both in 4x original resolution:

Code: Select all

mame.exe -aviwrite pacman.avi -snapsize 896x1152 -seconds_to_run 10 pacman

The video is 1.73 GB. I wonder how much hard disk space took some longplay videos rendered in HD that can be found on YouTube - before they were compressed :-O

Interesting, there is a note:
Note that this size does not automatically rotate if the game is vertically oriented. The default is ‘auto‘.

but the video is as expected despite Pac-Man is vertically oriented game (at least I think it is).
Chupo_cro
mhoes
Posts: 186
Joined: Wed Oct 26, 2016 12:26 pm

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

I'm glad it works and helped. But I'm afraid that's about the only help I can offer on this subject. All this stuff is really waayy over my head I'm afraid. One final note from me (and then I'll crawl back under my rock): There used to be this website "Let's Hack Arcade Games" (letshackarcadegames.com) that has unfortunately gone offline but fortunately has been archived by the 'Internet Wayback Machine Archive' [1] that has some articles on how to go about using the debugger. Although I'm fairly sure you know all of that already, I still thought it might turn out to be helpful to point it out.


[1]
https://web.archive.org/web/20161106154 ... om/?p=338
User avatar
chupo_cro
Posts: 4
Joined: Thu Jun 29, 2017 2:08 am
Location: Hrvatska

Re: VBLANK and interrupt? (debugging my own code for Pac-Man HW)

mhoes wrote: Wed Jul 05, 2017 5:13 pm I'm glad it works and helped. But I'm afraid that's about the only help I can offer on this subject. All this stuff is really waayy over my head I'm afraid. One final note from me (and then I'll crawl back under my rock): There used to be this website "Let's Hack Arcade Games" (letshackarcadegames.com) that has unfortunately gone offline but fortunately has been archived by the 'Internet Wayback Machine Archive' [1] that has some articles on how to go about using the debugger. Although I'm fairly sure you know all of that already, I still thought it might turn out to be helpful to point it out.


[1]
https://web.archive.org/web/20161106154 ... om/?p=338

As you have guessed, I indeed already know what was described in those pages (and I read all those articles a few days ago). The described methods are useful for the purpose of modifying existing ROMs but not so useful for gathering information I need to write the code from scratch. Pity they didn't continue writing the articles.

Well, although you might not be into programming the hardware based on 40+ year old µprocessors, you did know what I didn't :-) Everyone knows something somebody else doesn't - that is why there are forums such is this one, to be able to hear from people who know something you don't.

Thank you again for your help!

Best regards
Chupo_cro

Return to “MAME Discussion”