The SOCoCo-80
Project |
|
Back to the Drawing Board
|
|
Rethinking the
Video Controller
|
|
With my work on the DDr functionality and it’s complexities, I decided to take a brain rest and take another look at the video. Although in the past, I had a working prototype of the video controller with many modes working, it wasn’t complete. So, I decided to finish the video driver as a way to relieve some brain pain. Taking the code in an earlier blog, I created a test project. I actually used the code from the blog because in an effort to clean up my project files, I deleted my video source files. Silly me. I placed the function in this new project and fired her up. And to my shock… No Video (well sort of)!!! What? This was working fine when I posted it. I spent two days trying to track down the problem. I was convinced it was a timing problem. I was getting video colors but no access to the video RAM. No pictures were showing after I downloaded them. Looking at the specs of the RAM chip, I noticed that the valid data area was about 8 nsec after the address lines were stable. My code was reading immediately. To correct the problem, I split the clock into two phases. i_CLOCK and i_eCLOCK where i_eCLOCK is 90 degrees lagging i_CLOCK. I placed the data fetch function in the i_eCLOCK, fired her up and BINGO… same problem. Man was this frustrating. What could be wrong. It worked before. I also noticed when it was working. I was passing control signals through an mmu function. This was my attempt at interfacing the video and CPU. My new thought was that somehow the mmu delays were just right to get the RAM to work. This would be a problem because the access was to sensitive to hardware changes. It was late on Saturday, while watching the Blackhawks win against Boston I was parooszing the test code. HOLY CRAP!!! I see it!! It’s right in front of me! The problem wasn’t in the video code, it was in the quickie test function I wrote. I declared the RAM address bus as an input not an output. Changing this to an output made everything all good again. My code worked fine. However for now, I plan on leaving the 90 degree lag in the timing. |
|
A New Mode
|
|
Continuing to finish the video driver I am organizing it for a typical
CPU interface. I added a chip select, Read/Write, Data In, Data Out
(wishbone) and Register Select lines. These will operate as any digital
interface chips signals will. The RegSel lines will
connect to the CPU lower address lines to allow the selection of several
registers. Data In, Data Out and R/W are self-explanatory and the chip select
will act as a strobe. This may change to a clock signal later. One by one, I wrote and tested each video mode. I started with the
graphics modes because they are the easiest to implement. Basically they all
work the same way. The code generates a RAM address based on the horizontal
and vertical counters in the sync generator. The data from the RAM is then
read in at the location of the address. After some discrimination processes,
a color value for the Red, Green and Blue is calculated based on the mode.
These values are puked to the hardware for display. 640x480x64 colors 320x200x64 colors These modes are one pixel per byte where
the byte is divided: xxBBGGRR The 2 bits for each color gives 4 levels
of that color (4*4*4=64 total colors). The two “xx” bits are not used and are
ignored. 320x240x256 colors 640x480x256 colors One would think that this would be the
easiest to implement but it’s not. Researching this mode I discovered that
there a couple of approaches that can be taken. Either calculate
the color based on some formula or have a look-up table. I opted for the
look-up table. Using a ROM simulator I created a 2 byte per color register.
The table was hand written in a text editor and the values were that of the
standard Windows 256 color BMP tables from PhotoShop.
I used this table to make it easier to transfer pictures from other computers
as it seems to be one of the main standards. 320x240x16 colors 640x480x16 colors This mode will use a “user programmable”
palette register group. Just like the CoCo, a 16 register group will be
assigned to each nibble in the video memory. The palette register will actr as a look-up table for each of the 16 values in the
nibble. Xxxx yyyy This poses a small problem though, the
other modes above has 1 pixel per byte. This mode (and others to follow) will
have 2 pixels per byte. I needed to make some changes in the way I was
creating the RAM address calculations to facilitate these modes. It
complicated the source a bit but it works fine. 320x240x16G 640x480x16G These are
two new modes I added from the original specification. This is
basically a 16 level grey (or is it gray?). mode. I
implemented it just because it wasn’t too far from the 16 color mode and it
just took me about a hour
to test. I still have some work to do on the driver. The text modes and the 2
color modes are next. But, with looking at the timing with a larger
magnifying lens, I’m thinking that I might be able to go back to doing this
entirely in static RAM, CPU and Video. It’s looking like what I thought was a
RAM speed problem may have been the way I implemented the MMU. I will put the
CPU back in and rewrite the MMU controller once I get the video done. Oh, one more thing… I had to change the video timing generator
slightly because that pesky extra pixel showed it’s
ugly face again. I found another counting error that needed some attention. I
won’t say it’s fixed (been there – done that) but it seems somewhat better. I do plan on posting the code later this week. I might wait until I
get the text modes working though. I haven’t decided yet. We keep moving forward… |
|
|
© 2013 – Franklin
Laboratories |
No comments:
Post a Comment