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

Modifications of the json format #14

Open
Manuel-K opened this issue Jul 20, 2023 · 5 comments
Open

Modifications of the json format #14

Manuel-K opened this issue Jul 20, 2023 · 5 comments

Comments

@Manuel-K
Copy link
Contributor

I'm working on a launcher (not uploaded at the moment) for the vpinball standalone branch that displays last game scores/high scores and keeps an own high score table.

I've got several additional maps (only score related addresses), but I've made three modifications to the format:

  1. an "upper_nibble" option for unpacked bcd encoding – needed for some of older roms
  2. made "endian" of "score" override "_endian" of file, i.e.
if self.entry.get('endian') == 'little' or (not self.entry.get('endian') and not self.metadata['big_endian']):
                ba.reverse()

in https://github.com/tomlogic/py-pinmame-nvmaps/blob/master/nvram_parser.py#L117 which is what I assumed it was supposed to do, but the reference code didn't.
3) named "last_game" entries for team scores in addition to the normal unnamed ones

I'm still reorganizing code, so it might take a while, but what do you propose to do? Do you want to include the maps that require those changes?

@tomlogic
Copy link
Owner

Let's hold off on the maps for the moment, and work out the changes to the JSON format first. We can then update the Python reference implementation to match the file format documentation.

I was looking at the "upper nibble" issue earlier, when working on maps for Stern Dracula and Wild Fyre, which use identical ROMs in a Stern M-100 MPU. I made the following notes on how to handle bytes with only a single nibble, by adding an optional nibble attribute that defaults to both but you can set to either low or high. We could potentially deprecate packed=false and replace it with nibble=low.

packed=true -> replace with nibble=both
packed=false -> replace with nibble=low
nibble=high -> new setting, necessary for these games

We probably need to update the README to specify that implementations should treat nibbles 0xA to 0xF as 0 when converting BCD. On Dracula/Wild Fyre, the ROM uses 0xF to display a blank instead of 0.

RAM1 is volatile 128 bytes at 0x000
RAM2 is non-volatile 256 bytes at 0x200

0x23A is number of credits
0x237 is match (reset on power cycle)

0x013 is current ball
0x014 is player count (0 if no game in progress)
0x015 is current player

Player scores start at 0x23C. High Score to Date at 0x2CF. Game has a 6-digit 7-segment display for each player. Scores are stored in 6 bytes as BCD with some oddities.

  • an "F" represents a blank digit
  • scores are stored as 6 bytes, but only high nibble used
  • low nibble of odd bytes (1, 3 and 5) is 0
  • low nibble of even bytes (2, 4, and 6) is a duplicate of the high nibble of the previous byte.
  • scores are little endian -- smallest digit is first
  • 00 00 F0 F0 F0 F0 shows as " 00"

0x21E to 0x235 looks like some sort of attract text? Definitely display memory, based on entering test mode.

@tomlogic
Copy link
Owner

Thanks for the tip on the condition for the entry overriding the file's setting. I see that I'm not correctly handling the case of the entry specifying big endian when the file's default is little endian. I wonder if it would be clearer to do something like the following (hopefully my Python syntax is correct).

self.entry.get('endian', 'big' if self.metadata['big_endian'] else 'little') == 'little'

It might make sense to add a method to the entry object so future code can just do self.entry.big_endian() as a shortcut. What are your thoughts on that?

@Manuel-K
Copy link
Contributor Author

Manuel-K commented Jul 21, 2023

Only some notes now, I'll have to think about the rest later.

On Dracula/Wild Fyre, the ROM uses 0xF to display a blank instead of 0.

Xenon (and similar roms) do that as well. I'm currently only treating 0xF as 0, but I've also added 0xFF for packed as 0, although I currently don't remember which rom needed that. If we just say that 0xA – 0xF is 0 then the code could be simplified to & 0x9 (well obviously not)

I wonder if it would be clearer to do something like the following (hopefully my Python syntax is correct).

Looks correct, but I'm not sure that that is easier to read. The python equivalent of ?: is usually frowned upon, but … or ( … and … ) is probably not better.

In the implementation that I use, I decode the values in a separate function that gets only a small part of the json data and the global endian value and then just does:

    if big_endian_override := mapping.get("endian"):
        big_endian = big_endian_override != "little"
    if not big_endian:
        raw = reversed(raw)

which obviously only works in python >= 3.8.

@Manuel-K
Copy link
Contributor Author

The nibble change looks good with

    nibble = "low" if mapping.get("packed") == False else "both"
    nibble = mapping.get("nibble", nibble)

Now I'm using the ?: myself, but I think it's okay if it isn't stuffed in a single line

@Manuel-K
Copy link
Contributor Author

It might make sense to add a method to the entry object so future code can just do self.entry.big_endian() as a shortcut. What are your thoughts on that?

Yes, that can't hurt.

Did I miss anything?

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

No branches or pull requests

2 participants