Jump to content
IGNORED

Geneve GROM emulation


mizapf

Recommended Posts

I found some interesting details about the GROM emulation inside the Gate Array. This happened while I was redesigning some parts of the Geneve emulation inside MAME, in particular, while going from the high-level emulation to a more chip-related emulation. Most interesting, I (and Raphael Nabet, my predecessor in terms of MAME TI emulation) was wrong with a few assumptions, most are correct, however.

 

1. The GROM emulator allows for 8K GROMs and GRAMs (you can store values at addresses >1800->1FFF).

2. Setting the GROM address to n automatically increases it to n+1. This is the first location where values are read from or written to. If you set the address to >1000, reading starts at >1001. This is an implementation error in the Gate Array; the real GROMs behave differently (setting to address n makes the GROM read the value at that location into the output buffer and then increase by 1).

3. The GROM address counter wraps at >1FFF (>3FFF, ...>FFFF). This was falsely emulated as only wrapping at >FFFF. If you set the address to >5FFC and start reading, bytes are read from 5FFD, 5FFE, 5FFF, 4000, 4001 etc.

4. Reading the address register destroys its value. Similar to the real GROMs, reading a value from the address register delivers the MSB and copies the LSB on the MSB. If the address register contains >1234, you will read the values >12, >34, >34, >34, >34, ... This was not correctly emulated either.

5. Writing a byte into the address register first copies the LSB into the MSB and then writes the new byte into the LSB. On the second write, the value is then incremented by one. If you intermediately read the register, the write count is reset. So if you write >2000 into the address register, then write >32, it contains >0132 (remember the +1 after the first set). If you then write >10 into the address register, it contains >3210 (not incremented). Lastly, if you write >10 into the register, it will contain >1011.

 

Edited by mizapf
Fixed #1
  • Like 3
Link to comment
Share on other sites

Yes, I actually checked in on my real Geneve. Raphael Nabet already stated this effect in his early works.

 

If I want to read the byte from GROM position 0000, I have to load 1FFF into the GROM address register.

 

Mind that the GPL interpreter of the Geneve is heavily patched anyway; the keyboard routine already is pretty different. I can imagine that they also patched the GPL commands in a way that this behavior is compensated.

 

Link to comment
Share on other sites

Here is the program:


       DEF  GROM1

GROM1  LI   R1,>3800
       MOVB @>8006,R2    Keep old value
       MOVB R1,@>8006    Map page >38 (GROM 0) into >C000
       LI   R0,16
       LI   R3,>C000
       LI   R4,10000
G1C    MOVB *R3+,*R4+    Copy 16 bytes from >C000 to 10000
       DEC  R0
       JNE  G1C
       MOVB R2,@>8006    Restore value
       
       LI   R0,>1FFB     
       MOVB R0,@>9C02
       SWPB R0
       MOVB R0,@>9C02    Set GROM address to 1FFC
       
       LI   R0,16
       LI   R4,11000
G1D    MOVB @>9800,*R4+  Copy 16 bytes from G>1FFC to 11000
       DEC  R0
       JNE  G1D         

       MOVB @>9802,R2    
       SWPB R2
       MOVB @>9802,R2
       SWPB R2     
       MOV  R2,@10500    Save the current GROM address to 10500
       BLWP @0           We messed up the GROM address; reset

 

The photograph shows that the second sequence of bytes is shifted by 4, which means the first address is indeed G>1FFC, then it wraps back to G>0000, and the counter at the end is >000C.

gromread.jpg

  • Like 2
Link to comment
Share on other sites

36 minutes ago, mizapf said:

Yes, I actually checked in on my real Geneve. Raphael Nabet already stated this effect in his early works.

 

If I want to read the byte from GROM position 0000, I have to load 1FFF into the GROM address register.

 

Mind that the GPL interpreter of the Geneve is heavily patched anyway; the keyboard routine already is pretty different. I can imagine that they also patched the GPL commands in a way that this behavior is compensated.

 

Ah, okay.. I guess that makes sense. But code that uses GROM for data storage would still be affected. Was the GPL compatibility of the Geneve lower than 100%?

 

At this point I guess it's academic for me, I'll likely never have a Geneve.

Link to comment
Share on other sites

One more key piece of information is that the TI Mode program "GPL" accounts for this one byte offset during the initialization and load processes.   At initialization, GROM0/1/2 are copied into pages >38,>39,>3A with a one byte offset. The same process occurs when GPL loads a GROM cartridge file into one of the GRAM/GROM banks.  ROM is copied without an offset.   If I remember correctly, programs like BOOT for the TI won't properly load cartridges into the Geneve.

 

Here is some relevant info from J.P. Hoddie's programming notes:

 

image.thumb.png.52996348de9bac17aa7842139c7b3361.png

  • Like 3
Link to comment
Share on other sites

I just stumbled over this page 03 issue in my test program, wondering why I only got 00 when reading from GROM. I used the C000 area for direct access to the GROM page. I can't imagine why this mapping is necessary; the C000 frame does not have anything to do with sound (9400) or GROM (9800), and page 03 is on physical addresses 006000-007FFF.

 

This was actually not emulated in MAME, which was a bit of a surprise when my test program that was running well on the emulated Geneve now returned only 00 on the real iron. Will be fixed for next release.

 

 

  • Like 2
Link to comment
Share on other sites

Just verified it with my real Geneve. The first picture shows four blocks of bytes: (1) the first 24 bytes in page >38, (2) the first 24 bytes in page >3B, (3) the first 24 bytes read via >9800 after setting GROM address >0000, (4) the first 24 bytes read via >9800 after setting GROM address >6000. As already stated above, the pages contain the GROM contents with an offset of 1, wrapping the last byte to the first position.

 

The second picture shows what happens when you map the GROM pages into address area >C000->DFFF, which I actually did first. This is when you start getting doubts about your mental sanity, or whether you are just overworked. I did not know (or forgot about) the fact that page >03 must remain mapped to address >C000.

grom1.jpg

grom2.jpg

  • Like 3
  • Haha 1
Link to comment
Share on other sites

I found out a bit more; the story is not over yet. I mean, you can still ask what the meaning of 00 is. ?

 

Actually, I wanted to find out what happens when the page 03 is not mapped at >C000 and you are accessing the GROM address register. One result was that when you read the address register and page 03 is not mapped, you get >0202 as the GROM address, regardless of what you set before.

 

Do you see the connection?

 

Spoiler

 

The value 00 (or 02 when reading the address) is the low byte of the GROM port address. This byte was the last value read via the data bus as part of the MOVB command (in the source part). The Gate Array does not respond to the read operation because the page 03 is not mapped, so it seems that this value remains latched in the processor data bus input.

How to verify? - The Gate Array does not fully decode the GROM address, you can use 9802, 9806, 981A etc. with the same effect. Likewise, the data read port is 9800, 9804, 9858 etc. There is no RML feature inside the Gate Array. If you use these alternative port addresses, you see their lowbytes in the output

 

 

Edited by mizapf
Link to comment
Share on other sites

It is page 03, not 6 (do you refer to the memory regions?). I don't believe that the bits (0000 0011) have a meaning for setting the GPL mode, since it would mean that setting them to another value could turn off the GPL mode. This does not seem the case, as you can see with the video output (the video ports would be F100 instead of 8800 etc.) which is still working.

 

It is pretty obscure to me why this value must be set in the map register at address 8006. Maybe a side effect? Unless we find the equations for the Gate Array some day, we can only guess.

 

(I'm inclined to say at this point that the Geneve never lost its fascination for me over all those almost 30 years...)

Link to comment
Share on other sites

On 9/24/2019 at 7:00 PM, mizapf said:

I just stumbled over this page 03 issue in my test program, wondering why I only got 00 when reading from GROM. I used the C000 area for direct access to the GROM page. I can't imagine why this mapping is necessary; the C000 frame does not have anything to do with sound (9400) or GROM (9800), and page 03 is on physical addresses 006000-007FFF.

 

I thought it was a safety measure intended to minimize accidental GROM page access when in 9640 mode (OS, XOPs, interrupts etc).  If grom access was enabled at all times, writing to the port addresses and their mirror addresses could trash bytes in the 8 gram pages.  Was it designed this way up front or was the effect found later and fixed with this weird page requirement?  Lou might remember, not sure anyone else would know...

  • Like 1
Link to comment
Share on other sites

1 hour ago, mizapf said:

It is page 03, not 6 (do you refer to the memory regions?). I don't believe that the bits (0000 0011) have a meaning for setting the GPL mode, since it would mean that setting them to another value could turn off the GPL mode. This does not seem the case, as you can see with the video output (the video ports would be F100 instead of 8800 etc.) which is still working.

 

It is pretty obscure to me why this value must be set in the map register at address 8006. Maybe a side effect? Unless we find the equations for the Gate Array some day, we can only guess.

 

(I'm inclined to say at this point that the Geneve never lost its fascination for me over all those almost 30 years...)

Yeah, I meant bank not page. 

 

As InsaneMultitasker said, it's controlling whether the GROM addresses appear in >9800 for GPL, but as you pointed out there's more to GPL behavior, like VDP ports. Also wait states.

 

 

It should have been intentionally designed this way, since it's baked into the gate array, or maybe it was supposed to be just slightly different, and this is what we got. I would have chosen to require some particular page number  at >8000.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...