Jump to content

SeaGtGruff's Photo

SeaGtGruff

Member Since 7 Aug 2005
OFFLINE Last Active Yesterday, 11:24 PM

Topics I've Started

Question about writing a TIA simulation

Tue Dec 20, 2011 11:11 PM

I'm not sure if this is the best place to post this, but here goes.

For several months now (perhaps even years), I've been studying the TIA schematics on and off to try to understand how to read them, and how the TIA works. I still have some questions about reading certain things in the schematics, but I think I now understand how to read most of the sections.

Many months ago I downloaded LTspice with the intention of trying to set up the schematics in it so I could run it and follow the action, but that was a bust, because I don't yet understand how to set up the different circuits (transistor parameters, etc.).

Much more recently I've started working on a spreadsheet to simulate the TIA. (Yes, I'm crazy.) I have most of sheet 1 of the schematics set up in a spreadsheet, with every inverter, NOR gate, AND gate, flip-flop, etc., implemented as a column. I've even added randomization for lines and nodes that might have undetermined values at startup, such that (for example) the horizontal sync counter now starts up with a random value, possibly even the illegal 111111 value. I don't know if the randomization is realistic, but it's kind of neat to see that the phi0 clock pulse might start out with an oddball pattern (such as 00001100111000) before stabilizing to 111000111000, and things like that.

The problem is, my spreadsheet is based on a delay of 0-- each row corresponds to a high or low cycle of the oscillator, with no rise time, no fall time, no propagation delays, no gate delays, etc.

If posible, what I'd like to do is create a software implementation that tries to incorporate rise times, fall times, gate delays, etc., so I can get a better idea of the timing for different events-- like, how long does it take after the SHB signal before the blanking actually kicks in, etc. But I'm not sure the best way to approach it. I'd like to simulate every individual gate and signal-- for example, simulating the inner workings of the divide-by-3 or divide-by-4 sections, or the horizontal sync counter LFSR-- rather than just reading the next value from an array. I'd like to use voltage levels rather than simple 1 or 0 values, but I'd be happy to start with simple 1 or 0 values as long as I could incorporate the delays at least well enough to get a rough idea of timing. (The old Stella programming guides do include tables and diagrams with timing values, so that helps.)

I'm *not* trying to write a full-blown emulator per se-- I have no interest in emulating the 6507, the 6532, the TIA, different cartridge formats, etc.-- I'm more interested in a "slow-motion simulator" to follow the inner workings of the TIA, the general timing of the signals, etc., rather than running a ROM image and drawing a video display.

Can anyone tell me how existing emulators work? What I mean is, do they account for things like the delay between the phi0 clock signal and the phi2 clock signal, or do they operate on a more simplistic 0-delay implementation that focuses on final results rather than the nitty gritty of all the gates and signals that produced those results?

Some TIA schematic questions

Sun Jul 17, 2011 12:04 AM

I have a few questions about some things in the TIA schematics.

Attached File  OSC.PNG   144.58K   35 downloads

Question 1: What is the five-sided symbol immediately after the OSC pin? Does it represent a digital-to-analog converter?

Question 2: The signal from the OSC pin goes to inverter D (the letter D refers to a particular type of transistor, as listed on sheet 5). Then the signal from inverter D is split, with one line going to inverter A and the other line going to inverter G. But then the signal from inverter A goes to inverter G. So what comes out of inverter G?

Example:
OSC = 0, 0 -> inv.D -> 1 -> inv.G -> 0
OSC = 0, 0 -> inv.D -> 1 -> inv.A -> 0 -> inv.G -> 1
Does inverter G output 0 or 1? Or does it start at 0 and then change to 1?

Example:
OSC = 1, 1 -> inv.D -> 0 -> inv.G -> 1
OSC = 1, 1 -> inv.D -> 0 -> inv.A -> 1 -> inv.G -> 0
Does inverter G output 1 or 0? Or does it start at 1 and then change to 0?

I'm guessing the answer has something to do with (a) the signal being analog, so it isn't high or low per se; (b) the different specs for transistors A, D, and G; © propagation delay; or (d) some combination of the above-- but I can't figure out what the output of inverter G will be. This type of thing shows up all through the schematics, so I want to be sure I'm interpreting it right.

Attached File  D0.png   119.56K   33 downloads

Question 3: What is the symbol between the first inverter A and the second inverter A, where the line from the D0 pin crosses the Φ2 line? I'm guessing it might be a cell; is that right? If so, what value will it store? The same goes for the second one that cross the /Φ2 line.

Thanks in advance.

Michael



TIA Sound

Thu Jul 7, 2011 1:29 AM

As I've mentioned in other threads, lately I've been preoccupied with TIA sound. I want to understand it from the ground up. So in addition to reading through all of the old [stella] mailing list posts about TIA sound, I've also been trying to learn whatever I can about sound and music in general-- sound waveforms, frequencies, tuning systems, synthesis, MIDI, etc. I've even gone so far as to start collecting books about computer sound, electronic music, and "soft synths." This has been going on to various extents for a while now-- months, if not years-- but just recently I've really been focusing on it more and more, almost obsessively (it's my newest "shiny object").

Last week I wrote a little program that runs through every combination of AUDC0 and AUDF0. It plays 7 seconds of AUDC0=0, AUDF0=0; then 7 seconds of AUDC0=1, AUDF0=0; then 7 seconds of AUDC0=2, AUDF0=0; etc. After it goes up through AUDC0=15, it starts over again with AUDC=0, but with AUDF0=1; then with AUDF0=2; etc. I chose 7 seconds because I wanted to make sure each sound frequency had a chance to repeat a few times, even with the lower frequencies. It just so happened that it takes about 1 hour to cycle through all of the AUDC0/AUDF0 combinations. AUDV0 is set to a fixed value of 15 the whole time. I know it's pointless to play AUDC0=0 and AUDC0=11 this way, and that some AUDC0 settings yield the same results as each other (e.g., AUDC0=4 and AUDC0=5), but I really wanted to go through all the possible combinations, and I figured the occasional periods of silence would be useful when I recorded the output and analyzed it.

So the other night I put the program on my Krokodile Cartridge, hooked up my Atari 2600 to my VCR, then to my DVD recorder, and recorded the program's output on a DVD at the highest quality (1 hour). Then I used the Any Audio Converter program to convert the DVD's soundtrack to WAV files, and started using the WavePad Sound Editor program to examine the WAV files. Unfortunately, the WAV files came out to be sampled at 48000 Hz, which doesn't jive very well with the TIA's base audio frequency of about 31400 Hz, so that makes it tricky to examine the higher frequencies. Still, I've been able to use the lower frequencies to check the higher frequencies. For example, AUDC0=1 and AUDF0=0 is tough to analyze by itself, but I can look at AUDC0=1 and AUDF0=1, then AUDF0=2, then AUDF0=3, etc., to see how the waveform gets longer, and then the bit pattern of the waveform becomes easier to see.

I haven't finished my analysis, but right away I started freaking out about what I'm seeing. For example, where I expected to see pulse waveforms, instead I'm seeing something that's more like a cross between a sawtooth waveform and a pulse waveform. In other words, it jumps up to a peak, but then starts decreasing like a sawtooth wave, then jumps down to a valley, then starts climbing back up like an inverse sawtooth, then jumps back up again. I started to worry that there might be something seriously amiss with the way I'd gone about recording, converting, and analyzing the sounds, but then I realized it makes perfect sense. After all, a steady stream of 1s is silent, since there's no oscillation going on. So if you're alternating between 1s and 0s, but each value lasts for more than one occurrence (e.g., 1111000011110000 etc.), the change from 1 to 0 or 0 to 1 results in a peak (1) or valley (0), but then as the same value continues, the amplitude starts to move toward the center, where it would flatline if it continued long enough. So 10101010 jumps up and down as expected, but 1111000011110000 jumps up, then starts to flatline, then jumps down, then starts to flatline, etc., resulting in a waveform that looks like the following:

Attached File  AUDC0=6, AUDF0=5.png   34.64K   31 downloads
AUDC0=6, AUDF0=5

And the longer the value stays the same, the more the waveform will flatline between each peak and valley:

Attached File  AUDC0=6, AUDF0=12.png   36.08K   32 downloads
AUDC0=6, AUDF0=12

Attached File  AUDC0=6, AUDF0=19.png   35.2K   29 downloads
AUDC0=6, AUDF0=19

Another thing I'm noticing is that the waveforms don't always follow the bit pattern I was expecting. AUDC0=1 (the 4-bit LFSR) is the best example. Apparently the TIASOUND.C code said that the pattern is 111100010011010. But then Adam Wozniak said that it's actually 000011101100101 (i.e., that the 1s and 0s should be reversed). I'd been relying on Adam's old [stella] posts, because he took actual samples and eventually figured out the logic for the more obscure waveforms. But what I'm seeing is that TIASOUND.C was actually correct-- it's 111100010011010.

I'm also seeing that AUDC0=6 and AUDC0=10 are sometimes inverted-- these are the 31-bit waveforms that are supposed to have 13 highs followed by 18 lows. Sometimes it's actually 18 highs and 13 lows. I suppose the sounds sound the same either way, but I still think it's interesting that the "duty cycle" isn't consistent.

I've started working on a document that summarizes my understanding of TIA sound, and I'll post it when I'm done. I've been making some assumptions, and I don't know whether they're correct or not, but it seems like they should be. For example, my attempts to decipher the TIA schematics showed that the TIA generates an asymmetrical pattern of A-phi-1 and A-phi-2 pulses for each scan line. When I posted about that in [stella] a year or two ago, Eric Ball mentioned that he'd also noticed this, and had written about it in his AtariAge blog. At first I was sort of obsessed with how that might sound, but I've since concluded (or assumed) that the A-phi-2 clocks are the important ones-- or rather, the transitions from A-phi-1 to A-phi-2-- which yields a 28-29 waveform that divides the scan line as nearly in half as is possible using 57 counts per scan line. So I'm asuming that when you have a waveform bit pattern like 111100010011010 (the 4-bit LFSR with AUDF0 set to 0), each bit lasts for either 28 or 29 counts, rather than lasting for the exact same duration.

Anyway, I'm finding all of this to be very interesting (otherwise my current obsession wouldn't have lasted for very long before the next "shiny object" captured my attention!). One thing I'm getting out of this is that when David Crane mentioned using the "triangle" or "sawtooth" wave when he was programming Pitfall (I forget what he actually said), he might not have been speaking in error, or confusing Pitfall with Pitfall II as I'd originally assumed. :)

Michael



Colors (again!)

Wed May 25, 2011 3:24 AM

This week I reviewed the old [stella] posts in which Eric Ball gave formulas for calculating the RGB values for the 2600's NTSC color palette. I managed to create a Visual Basic program to calculate the colors, although I haven't quite completed it yet-- I still need to add gamma correction, as well as controls for adjusting the parameters, and I want to try to add additional "TV" controls for brightness, contrast, color (i.e., saturation), and tint. I understand most of the formulas he posted, and actually replaced some of his numeric coefficients with the parameters they're derived from (i.e., the RGB weights and the UV scaling). But I still don't understand how he got the TIA's luma increment and saturation value.

I also reviewed the field service manuals for the 2600, 5200, and 400/800 computers. Contrary to my previous belief, they *do* say that hue 15 should be adjusted via the color delay pot so it's the same as hue 1. I'd previously interpreted the wording to mean that hue 15 should be adjusted to fall somewhere between hue 1 and hue 2, because that's what the values in the GTIA documentation indicate (the time delay values it gives work out to a phase shift delay of about 27 degrees). But the illustrations in all three field service manuals clearly indicate that hue 15 and hue 1 should be the same color! I'll come back to this in a moment.

Another thing I found interesting is that Eric Ball's formulas-- or more specifically, the luma step increase he gave-- generate a palette that looks too dark, as everyone who replied to his posts had stated. However, I have an actual screenshot from my heavy sixer that I'd recorded to DVD, and not only does *it* look too dark when viewed on my computer screen, but it's actually a little bit *darker* than the palette Eric Ball's formulas produce! The difference between how dark the screenshot looks on my computer monitor versus how it looks on my TV must be due to the differences in the gamma, as well as the overall brightness settings.

So here's what I fnd so odd about the phase delay. When I set it so hue 15 is the same as hue 1, the palette actually does look "correct," although hue 15 and hue 1 don't look the same. Nevertheless, they are exactly the same, so their apparent difference is just an optical illusion because of the surrounding colors.

Also, I've compared different documents that specify or imply different phase delays.

For example, the documentation for the CGIA chip (which, as far as I know, was never produced) specifically stiplulates a phase delay of 24 degrees, which gives 15 different hues that are equally-spaced around the Y'IQ/Y'UV color wheel. This actually seems to match the way my heavy sixer is adjusted (which I didn't do myself; it came that way when I bought it a few years ago).

The Stella programming guide doesn't stipulate the phase delay value, but it does imply that the colors are equally-spaced over nearly 360 degrees, which *could* mean a 24-degree delay such that the span from hue 1 to hue 15 is 336 degrees (nearly 360 degrees obviously means *less* than 360 degrees).

As already noted, the field service manuals say hue 15 should be the same as hue 1, which is a phase delay of about 25.7 degrees (360 degrees divided by 14).

As I said above, the GTIA documentation lists timing values for each of the hues that are equivalent to a phase delay of about 27 degrees, which puts hue 15 exactly two-thirds of the way between hue 1 and hue 2.

I've also worked out several other possible phase delays between 24 degrees and 28 degrees, such as red=hue4, blue=hue9, blue=hue8, green=hue13, green=hue12, yellow=hue15, hue15="hue1.5" (exactly halfway between hue1 and hue2), and a setting that gives the closest simultaneous fit for red/green/blue (where red~hue4, blue~hue8, and green~hue12). Obviously, since different people might prefer to adjust the color delay pot differently, I want my palette generator to be adjustable. Personally, I feel rather strongly that hue15 should *not* be set equal to hue1, otherwise there's only 120 different colors, not 128.

Anyway, here's a few screenshots from my (unfinished) program, along with the screenshot from my heavy sixer, and one from my 7800.

First, my heavy sixer:

Attached File  Atari 2600 Colors.png   912.2K   31 downloads

My 7800:

Attached File  Atari 7800 Colors.png   849.45K   34 downloads

My Visual Basic program, with a delay of 24 degrees, as per the CGIA documentation (compare to my heavy sixer):

Attached File  phase 24.png   12.79K   32 downloads

My program, with hue15=hue1, as per the FSM (they may *look* different, but are exactly the same):

Attached File  phase 25.7143.png   12.75K   30 downloads

My program, with a delay of 27 degrees, as per the GTIA documentation:

Attached File  phase 27.png   12.8K   25 downloads

When I complete my program, I'll post it here so people can use it to create palette files for their emulators if they want.

Michael

Can someone test this on a Harmony cart?

Tue May 24, 2011 2:51 AM

Can someone try this out on a real 2600 using a Harmony cart? It's a tiny bit of self-modifying executable code that's been placed in Superchip RAM.

If it works, the screen should cycle through all 128 colors.

It works fine in the Stella and z26 emulators, but of course that doesn't mean it will work on a real 2600.

I'm not so much interested in whether it will work with an actual Superchip (although that would be nice to know, too), more whether it will work on a Harmony/Melody cart running an F8SC ROM image-- because if it does, that means we can run executable code in Superchip games sold on Melody carts.

I can test it myself on a Cuttle Cart II and a Krokodile Cart-- not now (I *really* need to go to bed ASAP), but maybe tomorrow night-- although I'm specifically interested in the Melody cart, since that's what games would be sold on. (I'm assuming that if it works on a Harmony cart, it should also work on a Melody cart.)

If I remember correctly, I'd previously been told that executable code won't work on a real Superchip. But I'm pretty sure "Video Life" runs executable code in its on-cart expansion RAM (watch it in Stella's debugger and you'll see what I mean). I don't know if any executable code was ever used in expansion RAM with an M-Network or CBS RAM+ game.

I'm thinking the main trick is simply to remember to *modify* the RAM code using the write addresses, but remember to *execute* it using the read addresses.

Here's the code. The program is in batari Basic, but it should still be simple enough for any assembly folks to understand. :P The "w000" through "w008" variables are simply the first 9 write addresses of Superchip RAM, $F000 through $F008, and the code is executed by a JSR to $F080.

   rem * Superchip RAM Test for Executable Code

   set romsize 8kSC

   rem * LDX #$00
   w000 = $A2
   w001 = $00

   rem * STX COLUBK
   w002 = $86
   w003 = $09

   rem * INX
   w004 = $E8

   rem * STX $F001
   w005 = $8E
   w006 = $01
   w007 = $F0

   rem * RTS
   w008 = $60

loop

   asm
   JSR $F080
end

   drawscreen

   goto loop
Michael