Subject: GROM internals

From: "Michael Zapf" <[email-masked]>
Date: Mon, 28 Jun 2010 20:36:10 -0000

So, here are some higher-stage questions for "Who wants to be a millionaire". I can't offer a million, but maybe I can get some self-sealing stem bolts instead (or a gallon of yamok sauce, specify).

I'd need some details on the timing in the GROM. I have not found any precise information on that - I guess that TI filed a patent and described the TMC0430 in there, so 

1. If there is not a specification somewhere, is there at least a patent describing the GROM chip? (Usually one can get them for free from USPTO.)

Now for some details.

2. What is the switch time of the address counter flipflop in the GROM when setting the address? You know that GROM addresses have to be set by two successive writes to the circuit with pins MO=1 and M=1. (MO is bound to A14). I would expect that there is a mandatory delay to respect.

3. What is the frequency of GRMCLK?
(Just checked: GRMCLK = XTAL/24, XTAL = 10.7 MHz -> GRMCLK = 445.83 kHz; OK, drop that.)

4. What is the delay time after reading a data byte from the circuit? And: Does the GREADY pin go down immediately after reading the data byte? This would mean that the CPU would be halted via READY. In that case you cannot read too fast, provided that you connect GREADY with READY of the CPU. Or is GREADY somehow bound to GRMCLK?

Thierry discusses the GROMs on his page, but cannot answer one question either: 

5. Why do you get ADDR+1 when reading the current counter? 

Assuming that Raphael's implementation in MESS is correct (but I don't know where he got the information from) there might be a plausible answer: GROMs have an internal 8-bit buffer which is loaded automatically, waiting to deliver the byte to the data bus. That is, you set the address, and the next thing it does is to load the eight bits into that buffer (and doing an addr++). When you read the data byte you get that buffered value, but addr is already one higher. After reading the byte the next eight bits are loaded and so on.

I'd hope for some timing diagrams as those in the TI-99/4A console specification. If there is something on WHTech it's at least well hidden.

Michael

---

From: "Tursi" <[email-masked]>
Date: Mon, 28 Jun 2010 23:14:01 -0700

I have GROM timing information taken right off the bus. Naturally I don't 
have the internal chip operation, but from what I get...

GROM operations don't seem to sync with the GROM Clock. This doesn't make 
sense to me, but I saw data transitions occur at all points in the GRMCLK 
line. Likewise, GRMCLK and the 9900 clock do not appear strictly in sync, so 
I observed *GSEL asserting at random points in the GRMCLK cycle. Since this 
results is a little weird, I wonder if some side effect may have caused my 
analyzer to report it.

Most operations seem to take 3-4 GROM Clocks. It partially depends on how 
quickly the 9900 releases *GSEL.

For instance, to read, the console first sets MDIR and MODE (from the 
address bus), then asserts *GSEL. Data appears 2 GRMCLKs later, then on the 
third clock GREADY goes high. GREADY stays high until *GSEL is deasserted. 
The normal state of GREADY is low.

During an address write, the first byte seems to complete 1 clock faster, my 
assumption was the extra clock is used for the prefetch.

Let's see if I can help at all on the actual questions:

2. What is the switch time of the address counter flipflop in the GROM when=
 setting the address? You know that GROM addresses have to be set by two su=
ccessive writes to the circuit with pins MO=3D1 and M=3D1. (MO is bound to =
A14). I would expect that there is a mandatory delay to respect.

There doesn't appear to be a delay after writing the first byte - as a 
simple flipflop its operation will likely be far faster than the 9900 can 
conceive, anyway. There seems to be a 1 GRMCLK delay anytime data prefetch 
occurs, based on the difference in time between writing the first address 
byte, and writing the second or reading data.

4. What is the delay time after reading a data byte from the circuit? And: =
Does the GREADY pin go down immediately after reading the data byte? This w=
ould mean that the CPU would be halted via READY. In that case you cannot r=
ead too fast, provided that you connect GREADY with READY of the CPU. Or is=
 GREADY somehow bound to GRMCLK?

Touched on above.. data is on the bus after 2 GROM Clocks and GREADY goes 
HIGH (not low!) to indicate ready on the third clock.

The 9900 is absolutely halted when GROMs are processing (confirmed in my 
GROM emulator - with full debug on it takes 24 GROM clocks to handle a read, 
and the console runs just fine, albeit slowly ;) ). GROM READY is always LOW 
when idle, but it is only gated onto the 9900 when *GSEL is active. READY 
goes high after every operation (when an address byte is accepted or data is 
available for reading) and goes low again immediately upon releasing *GSEL.

I think Thierry just didn't update his page - we covered this ages ago. Like 
the VDP, GROMs prefetch their data and increment their internal address 
counter. Since it's an automatic increment, the address counter contains a 
value 1 higher than the address of the byte in the prefetch buffer.

I don't think I saved any of my timing captures, but I may be able to get 
more this weekend if you want.

---

From: "Michael Zapf" <[email-masked]>
Date: Tue, 29 Jun 2010 12:37:05 -0000

Thanks so far, Tursi (and I'll see when I meet Nog next time for the stem bolts),

why I'm asking is that I found that some parts in the TI emulation in MESS are not strictly emulated but simulated, like the GROM access. The TMS 9900 seems to lack a READY line in the emulation which makes things somewhat complicated. I believe that I can simplify a lot of code if I do it "the right way", as in the real circuit.

Currently, the GROM delay is simulated by manipulating the command delay timer in the processor, i.e. when accessing slow devices, the processor "magically" slows down. I'd favor a new approach where I can control the READY line, so I should implement the proper GREADY timing behaviour.

Michael

---

From: "Michael Zapf" <[email-masked]>
Date: Tue, 29 Jun 2010 19:57:53 -0000

Hi Tursi,

one thing I forgot to ask: Considering GRAMs - they should work in a similar way as GROMs when being read. When I set the address in the GRAM, it will prefetch the byte at that address and auto-increment the counter. That's easy to understand when we only read, but what happens when we write a byte after setting the address? The address counter is already incremented.

I guess that the address counter will be decremented by one internally, then the byte is written. But will it also do a prefetch now? It must be ready for a possibly following read operation.

I had that problem in the HSGPL and GRAM Kracker emulation - when I set address >6000 and did a write, the byte went to >6001 which was obviously wrong, so I fixed it; I did a write to (addr + 0x1fff) % 0x2000. Looks ugly, but I don't know how else this is solved in hardware.

Expressed in code:

 LI R0,>6000
 MOVB R0,@>9C02
 SWPB R0
 MOVB R0,@>9C02
 NOP

* The byte at G>6000 is prefetched, and the address counter advances to G>6001. But what happens in the next line?

 MOVB R0,@>9C00 

* We would expect that the byte is written to G>6000 since we don't know anything about this internal advance. 

 MOVB @>9800,R1 

* We would expect that the byte from G>6001 is returned, since there was only one access before. But this means that the byte from G>6001 must have been prefetched when we wrote the byte above.

Michael

Michael

---

From: mark wills <[email-masked]>
Date: Tue, 29 Jun 2010 20:13:58 +0000 (GMT)

I believe you may be in "no man's land" regarding that question, since, to my knowledge, TI never manufactured any GRAMS...

If I'm right on the above, we're left with emulating existing behaviour from devices such as the MG GRAM Kracker.

Regards

Mark

----- Original Message ----
> From: Michael Zapf <[email-masked]>
> To: [email-masked]
> Sent: Tue, 29 June, 2010 20:57:53
> Subject: Re: [SPAM] [TI994A] GROM internals
> 
> 

Hi Tursi,

one thing I forgot to ask: Considering GRAMs - they 
> should work in a similar way as GROMs when being read. When I set the address in 
> the GRAM, it will prefetch the byte at that address and auto-increment the 
> counter. That's easy to understand when we only read, but what happens when we 
> write a byte after setting the address? The address counter is already 
> incremented.

I guess that the address counter will be decremented by one 
> internally, then the byte is written. But will it also do a prefetch now? It 
> must be ready for a possibly following read operation.

I had that problem 
> in the HSGPL and GRAM Kracker emulation - when I set address >6000 and did a 
> write, the byte went to >6001 which was obviously wrong, so I fixed it; I did 
> a write to (addr + 0x1fff) % 0x2000. Looks ugly, but I don't know how else this 
> is solved in hardware.

Expressed in code:

LI R0,>6000
MOVB 
> R0,@>9C02
SWPB R0
MOVB R0,@>9C02
NOP

* The byte at 
> G>6000 is prefetched, and the address counter advances to G>6001. But what 
> happens in the next line?

MOVB R0,@>9C00 

* We would expect 
> that the byte is written to G>6000 since we don't know anything about this 
> internal advance. 

MOVB @>9800,R1 

* We would expect that the 
> byte from G>6001 is returned, since there was only one access before. But 
> this means that the byte from G>6001 must have been prefetched when we wrote 
> the byte 
> above.

Michael

Michael

------------------------------------

Yahoo! 
> Groups Links

>   
> >http://groups.yahoo.com/group/TI994A/

> href="http://groups.yahoo.com/group/TI994A/join" target=_blank 
> >http://groups.yahoo.com/group/TI994A/join
    (Yahoo! ID 
> required)

> href="mailto:[email-masked]">[email-masked] 
> 
    
> href="mailto:[email-masked]">[email-masked]

> ymailto="mailto:[email-masked]" 
> href="mailto:[email-masked]">[email-masked]

> href="http://docs.yahoo.com/info/terms/" target=_blank 
> >http://docs.yahoo.com/info/terms/

---

From: "Ksarul" <[email-masked]>
Date: Tue, 29 Jun 2010 16:53:20 -0400

I'll try and scan in the documentation for the TI GRAM simulator cartridge
later this week, if work and school give me enough time to get to it.  I'll
also scan the docs for the GSIM (the silver pizza-box GRAM devices).  Note
one thing-a lot of additional data will also be found in Mike Bunyard's
Hardware Manual, as he included a reasonably complete description of the
circuitry and timing necessary to simulate a GROM in that book.  

Jim Fetzner

  _____  

From: [email-masked] [mailto:[email-masked]] On Behalf Of
mark wills
Sent: Tuesday, June 29, 2010 4:14 PM
To: [email-masked]
Subject: Re: [SPAM] [TI994A] GROM internals

I believe you may be in "no man's land" regarding that question, since, to
my knowledge, TI never manufactured any GRAMS...

If I'm right on the above, we're left with emulating existing behaviour from
devices such as the MG GRAM Kracker.

Regards

Mark

----- Original Message ----
> From: Michael Zapf <[email-masked] <mailto:newsmail09%40mizapf.de> >
> To: [email-masked] <mailto:TI994A%40yahoogroups.com> 

Hi Tursi,

I had that problem 

Expressed in code:

LI R0,>6000
MOVB 
SWPB R0
MOVB R0,@>9C02
NOP

* The byte at 

MOVB R0,@>9C00 

* We would expect 

MOVB @>9800,R1 

Michael

Michael

Yahoo! 

(Yahoo! ID 

> href="mailto:[email-masked]
<mailto:TI994A-digest%40yahoogroups.com> ">[email-masked]
<mailto:TI994A-digest%40yahoogroups.com>  

> href="mailto:[email-masked]
<mailto:TI994A-fullfeatured%40yahoogroups.com>
">[email-masked]
<mailto:TI994A-fullfeatured%40yahoogroups.com> 

> ymailto="mailto:[email-masked]
<mailto:TI994A-unsubscribe%40yahoogroups.com> " 
> href="mailto:[email-masked]
<mailto:TI994A-unsubscribe%40yahoogroups.com>
">[email-masked]
<mailto:TI994A-unsubscribe%40yahoogroups.com>

---

From: mark wills <[email-masked]>
Date: Tue, 29 Jun 2010 22:19:34 +0000 (GMT)

I have the Bunyard book. I read it just the other day. I can scan the appropriate pages if they are not available on-line.

Mark

>
>From: Ksarul <[email-masked]>
>Sent: Tue, 29 June, 2010 21:53:20
>Subject: RE: [SPAM] [TI994A] GROM internals
>
> >
>
>
>
> >
>
> 
> 
>
> 
>
> >
>
>
>
>
>
>
>
>>
>I’ll try and scan in the
>documentation for the TI GRAM simulator cartridge later this week, if work and
>school give me enough time to get to it.  I’ll also scan the docs
>for the GSIM (the silver pizza-box GRAM devices).  Note one thing—a lot
>of additional data will also be found in Mike Bunyard’s Hardware Manual,
>as he included a reasonably complete description of the circuitry and timing necessary
>to simulate a GROM in that book.  
> 
>Jim Fetzner
> 
>>
>>
________________________________
 >
>From:> [email-masked] [mailto:
> [email-masked] ] On Behalf Of mark wills
>I believe
>you may be in "no man's land" regarding that question, since, to my
>knowledge, TI never manufactured any GRAMS...
>

---

From: "Tursi" <[email-masked]>
Date: Tue, 29 Jun 2010 23:22:09 -0700

> one thing I forgot to ask: Considering GRAMs - they should work in a 
> similar way as GROMs when being read. When I set the address in the GRAM, 
> it will prefetch the byte at that address and auto-increment the counter. 
> That's easy to understand when we only read, but what happens when we 

Like Mark said, GRAMs were never official devices. GRAM devices, including 
TI's own simulator, has as their primary purpose acting as GROMs except when 
being written. So there's really nothing "official" for GRAM.

I'd suggest looking at how GRAM Kracker actually handles writes, they must 
have come up with something for it. Be aware that the GRAM Kracker and other 
devices don't HAVE to emulate GROMs 100% -- in particular at least one of 
the GRAM devices doesn't even support read-back of the address, it relies on 
the console GROMs to do that. Which means any trick they use for writing 
won't affect address read-back.

I agree with you that the prefetch causes issues -- that's why the VDP has a 
prefetch inhibit bit when setting the address. But GROMs weren't around long 
enough for the official resolution. We only have various interpretations. 
I'd be surprised if they all behaved 100% the same.

---

From: "Michael Zapf" <[email-masked]>
Date: Wed, 30 Jun 2010 08:18:37 -0000

Hello Tursi,

> I'd suggest looking at how GRAM Kracker actually handles writes, 
> they must have come up with something for it. 

yep, for the MESS emulation of GRAM Kracker (which I recently wrote) I had to guess what would be the most reasonable way to emulate the behavior. To my taste it became a bit too sophisticated, so I hoped for an official document. Probably it's indeed not worth thinking too much about it, since a circuit designed by a possibly discovered official document is not guaranteed to work with our software.

The easiest way to simulate the behavior would be to avoid the whole prefetching story but just deliver the address counter + 1. 

Michael