Hi Chad,
sburrow wrote:
Wow, thanks for the schematic. And great job on the video output, it looks really good! Congrats!
Thank you!
Quote:
I see the top-right corner you have some '590s spitting out A0 to A# (it got cut off, but it's a higher number). It seems those are going out. So that's output to the ROM and eventually RAM?
If those A's in the top-right corner are going to the ROM right now, and you want to replace it with RAM (so that you can make it useful of course), how will they share the address lines? You would have to bring data into it somehow? I make good use of those /G lines on those 590's myself!
You get right to the heart of the matter! I was just pondering that very thing.
In the top right I kind of sketched out an abstract zone for "frame buffer." Right now it's just a ROM, but eventually RAM, as you suggest. The cutoff part is A11. The low order 590 (7 bits) is what character we're on; the high order 590 (5 bits) is what row. So, the current character is a 12 bit address. This wastes some RAM, but made things a lot simpler. (I got the idea from Gerry Kane, so it's suitably retro.
)
As for how to interface... well... I'm not sure yet. Some options I'm considering (but there might be more I don't know of yet):
* Ignore it. Just give the CPU access to RAM willy nilly and live with some garbled output during video writes (this is oldschool, but I probably won't do it, because I don't like garbled video, and it's not a very fun way to solve the problem.)
* Dual port VRAM. This is what I'd like to do, but unless I can find some dual port ram that costs less than $13 per kilobyte (!) I probably won't go this route either. I've been reading some old threads where Dr. Jeffyl suggests you can roll your own "dual port RAM" using FIFOs and some logic, but that it's more complicated. This might not be so bad; I bet I would learn a lot from figuring out how to do that.
* Clock phase juggling. CLK_P is the master pixel clock of 25.175MHz. The output shift register needs to read from the character ROM once every 8 of those (so, roughly π MHz). The LOAD_P pulse that triggers the shift register loading is active LOW; when it goes HIGH, it clocks the lower order 590 to move on to the next charter. The 590s then just sit there for the next 7 pixels asserting the address of the current character. As long as we move in and out fast enough for the character ROM's outputs to settle before the next load, we should be able to write to the RAM here without disturbing anything. I think a 6502 at CLK_P2 (roughly 12.6MHz) should be able to do that, with a little clever gating. Could be tricky though. I will probably try this first, because I can do it with parts on hand.
Quote:
The Q0 to Q7 are those possible character sets right? You can set them to 00000000 and get one set, and then 00000001 to get another set, etc?
Q0 - Q7 is the output of the frame buffer ROM/RAM. All of the ROM data sheets call them Q (I guess because outputs are Q) but I think of them as D0 - D7. The two 590s input the 12 bit X,Y address of the current screen location, and whatever byte is stored in the frame buffer that location comes out on its Q0 - Q7. Those are fed into the ADDRESS lines of the character generator ROM, along with a 4 bit scan line code, which causes the character generator ROM to emit pixel data on its own Q0 - Q7 lines. IOW, the character generator ROM gets an ASCII code (8 bit extended in this case) and a scan line code (4 bits), and those 12 bits address one byte of pixels; hence, characters are 8 pixels wide and 16 pixels tall, because I am lazy about computer math and like to do things in bytes.
So, in case this is confusing (I'm finding it remarkably tricky to describe this in natural language), we have two different 12 bit addresses: one is a 5 by 7 bit address into the frame buffer that causes it to emit a byte of data. We will interpret that byte of data as an ASCII code, which is used as part of 12 bit address number two, which is an 8 by 4 bit address into the character rom that gets us one 8 pixel wide line of pixels out of the 16 lines of pixels we need to draw a whole character!
You can switch character sets by decoding A12, 13, and 14 on the character generator ROM, but right now I only have 2 character sets in there, so I'm just using a jumper wire on A12 to switch between them. (That is the meaning of the crudely drawn switch in that area of the schematic.)
Quote:
At about the middle-right you have some other 590's that are spitting out A0 to A14. Yet all 590's I see have /G grounded. So are those different address lines? One is for the timing ROM, another is for whatever is going outside (to the ROM/RAM)? So, different A's? Is there a way for you to combine those together?
I really like your use of the 590's, the 166, the 161, and the "timing" ROM. That is basically identical to what I'm doing. Didn't you start with something like what George (gfoot) uses? Me too, BTW
That's correct! The two 590s on the left are driving the timing ROM, the two on the right are scanning the frame buffer; separate address buses. The two timing ROM 590s are chained together to make a 15 bit counter, just like George's. The two on the right are clocked separately; one is for the row (i.e., the text row, 0 - 29) and the other is for the column (i.e., which specific character we're on, 0 - 79). George had everything come out of his ROM, including color data, since he was going for pixel-based graphics. Since I want a text terminal I got rid of all that and used two bits to create the HBLANK\ and VBLANK\ signals. I still have 3 unused bits coming off the timing ROM, but I haven't thought of anything interesting to do with them. The timing pulses are two characters (16 pixels) long, so they're two slow for any kind of character related data.
Quote:
Well, it seems you got the characters to display really well, AND the breadboard isn't giving you issues. So, good job, glad that's working! Thanks for the great update!
Thanks for taking such an interest in my project! The breadboards are behaving pretty well. A few twisted ground return wires for the longer signals helped a LOT. I did have a few breadboard related glitches to track down - a loose connection on one of the the column counter address lines was causing some ghostly intermittent repeats, but it seems rock solid now.