6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 4:28 am

All times are UTC




Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Wed Apr 19, 2023 7:22 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Yes, that's the idea, explored in a little more detail a couple of posts north.

I'm trying to expand Grant's minimal system to generate a 'nominal' vga output using the second processor as an address generator. It needs a bit of thinking since I want to use a single 32k eeprom which needs mapping into ram space.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 23, 2023 8:35 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Hmm, just walked into a problem while trying to allocate the various control and enable signals... disabling the bus with BE works with a single processor (and an absence of 6522s) but it occurs to me that with another processor sharing the RnW signal line, there is a possibility of writing to shared ram on successive halves of the cycle. Which isn't going to allow the ram ~we signal to return high before it's driven low again.

As one processor is largely operating either with ram data (e.g. a basic program) or is running from ram (probably with loads of zero page indirect addressing and stack usage) and the other processor is going to do a call and return at the end of every video line, that looks like a good chance of a timing collision. Bother.

I am beginning to suspect that my existing system works with BE and PHI2 connected is that there is still a pull-up resistor on the line; I need to hang a scope on it.

Perhaps it is necessary to qualify the rnw signal to the ram so that only the second half of the active time is used. Well, easily derived as I have x8, x4, and x2 dot clock divider outputs available.

Something to sleep on.

Neil

p.s. partial and definitely incomplete circuit diagram of thoughts so far.


Attachments:
Video interface controller (vga).pdf [686.44 KiB]
Downloaded 27 times
Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2023 10:09 am 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
Hm! I never thought of that. Yes, the /RW going tri-state is just strange to me (personally), maybe it was put into the design because of situations like this. Or not.

One thing, your 74LS166 has /CE connected to VCC. I don't think that is right, wouldn't that cause it to not work at all?

So, the overall thought here is to have one 6502 doing the processing, and then the other 6502 generating video signals?

Thanks for sharing!

Chad


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2023 2:54 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Good catch on the 166! I've been chopping and changing (it's been a 165 and a 597 already on this journey!) so thanks for the reminder. (it's connected to ground now!)

Yes, the idea is that the video 6502 does nothing but generate video lines (by running code in its rom that addresses video ram), blanking, and syncs. It doesn't decode A15 and A14 so it has only a 16k range; it can have code at 0xD000 which actually executes at 0x5000 and so addresses video ram from 0x5000 (or other convenient address); the main CPU runs across the full 64k with rom in the top quarter and ram in the bottom half.

The significant thing here to simplify the build is that both the rom (eeprom) and the ram are shared between the two processors.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2023 4:49 pm 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
Are they going to be using the same ROM chip? What I did was directly have those sync/reset signals in the ROM, thus I didn't need a 6502 to spit anything out. Also, I'm concerned that the 6502 would be "too slow" for this, because reading a byte takes a couple of clock cycles, and writing a byte takes even more clock cycles. In the end, if you just connected that ROM directly, it would cut out the slowness and complexity. You have your 6502's alternating PHI2 anyways, so it's not like you don't already have appropriate timing signals.

As far as fitting it in 16K though, it is tricky but doable. On my Acolyte SBC, I use 48K of ROM space for video signals, and the last 16K is for my program code (similar to your setup). On my Serial VGA module, I only use 32K of ROM for the signals, but I basically removed A0 and thus the video signals are running at half the speed of the main clock. The VGA monitor seems unaffected, it is telling me 60Hz and it's crisp and clean still using the full 640x480 pixel mode. I have been theorizing that I could get it to 16K if I tell it to read the first nibble on the first run, the second nibble on the second run. At some point on the second nibble run, it would reset my clocks and I'd start at the first nibble again.

Thank you, it's fun to see what others are doing :)

Chad


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 24, 2023 7:20 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Yes, they're sharing a 32k eeprom with ph2 being used to select the appropriate half. This is of course still a gedankensexperiment at present.

The fun is the timing of the blanking and syncs. Because I'm not generating any signals directly from the eeprom, the processor needs to drive some IO to do it and I'm not sure quite how that works the blanking (the syncs are easy).

Thinks: assume three flip-flops addressed at 0x0000, 0x0002, and 0x0004 - A0 is used as the data input and RnW as the clock (suitably qualified by the address decode of course). Writing to the base address clears the q output; writing one higher sets it. The flip-flops provide blanking, vsync, and hsync respectively. Every clock rising edge (from the video proc) latches the contents of the currently addressed ram location and starts clocking it out during the next clock cycle.

if I start a video line at (say) 0x5000/0xb000 and the first instruction at 0xb000 is sta #1 then I *think* the timing and address happens like this:
Code:
[time   ][addr. ][data]
[clock 0][0xb000][0x85] (sta #1, 3 clocks)
[clock 1][0xb001][0x01] (0x3000 data output by serial)
[clock 2][0xb001][0x01] (0x3001 data output by serial - blanking disabled)
[clock 3][0xb002][0xa9] (lda #0, 2 clocks - 0x3002 data output by serial)
[clock 4][0xb003][0x00] (0x3003 data output by serial)
...
[clock42][0xb02a][0x85] (0x3029 data output by serial)
[clock43][0xb02b][0x00] (0x302a data output by serial)
[clock44][0xb02b][0x00] (0x302a data output by serial, blanking enabled)
// do line sync stuff, inc line count


So as far as I can see, the video won't appear until clock 3, and it will show data from 0x3002 (for the first line) and I think I end up duplicating a character at the end of the line, so it'll need to be zeroed. So I may need as many as 45 memory addresses to output 40 characters, so I'm looking at 45 * 240 = 10,800 bytes (0x9b40) for the video memory. Which fits in the 12k I have available, with a little space for the code to actually drive it.

Using the 1.8432Mhz system clock, I get 59 clock cycles per so I can't just output every character and zero for blanking; it has to be active.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2023 7:51 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Possibly better explained with a picture (~= 1k words)

Neil


Attachments:
image001.png
image001.png [ 37.26 KiB | Viewed 856 times ]
Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2023 5:29 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
So here's a corrected version of the timing diagram.

Which tells me that approach isn't going to work; there's a byte picked up from 0x0001 as a result of the write to the blanking flip-flop which gets displayed after the blanking is disabled. Bother again. That would mean I have to ensure I have zero in the accumulator before that write. I also need a couple of unused addresses at the end of each line... my calculations above were obviously done too late at night, since 240 x 40 is 9600, not 8000... doh. Things are getting complicated...

Neil


Attachments:
timing2.png
timing2.png [ 31.26 KiB | Viewed 825 times ]
Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 25, 2023 8:48 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
OK, here's another picture... it assumes something as yet undesigned, which is a signal which is active when the video proc is addressing somewhere in the video range (which has moved to 4800-6fff). That signal is latched using the same signal that latches the PISO shift register.

Now it looks as if I need only reserve one byte at the end of each line with zero in it (or I could use 41 8-bit blocks on the line; either would work) to allow for the three addresses in three clocks for the final jump at the end of each video line; I'm always reading what I'm expecting in the video ram.

So I can lose one of the flip-flops, which saves a bit of board space, but I need to identify an address space from 0800-02fff (top two address bits aren't used).

Neil


Attachments:
video2.png
video2.png [ 46.16 KiB | Viewed 810 times ]
Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 26, 2023 10:09 am 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
barnacle wrote:
OK, here's another picture... it assumes something as yet undesigned, which is a signal which is active when the video proc is addressing somewhere in the video range (which has moved to 4800-6fff). That signal is latched using the same signal that latches the PISO shift register.

Now it looks as if I need only reserve one byte at the end of each line with zero in it (or I could use 41 8-bit blocks on the line; either would work) to allow for the three addresses in three clocks for the final jump at the end of each video line; I'm always reading what I'm expecting in the video ram.

So I can lose one of the flip-flops, which saves a bit of board space, but I need to identify an address space from 0800-02fff (top two address bits aren't used).

Neil


Though your pictures are detailed and understandable, I do not know the inner workings enough to understand why you are doing what you are doing. Are the LDA #$0 statements like NOP's kindof?

Chad


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 26, 2023 3:43 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Ah, yes, my apologies for not perhaps being as clear as I might have been on this one... It's kind of got spread out among a few threads.

The project is to extend a minimum-chip 6502 solution to include a VGA pixel-addressable output and a 6522 with an interface for a PS/2 keyboard, while maintaining the 1.8432MHz clock to keep the serial port at a happy bit rate. Every main clock cycle I output eight pixels on a line.

The idea is that a second 6502 (VIC) is used to generate the address from which a video ram will be read while executing code from eeprom. To do that, it needs to execute code somewhere between 0x4000 and 0x7fff which will be the video ram as seen by the main processor, running on the opposite phase. LDA #0 is one of a handful of instructions which both take two bytes to describe and take two clock cycles to execute, so if the ram output is isolated from the databus at the appropriate time, and the eeprom output connected, the VIC can execute code which takes an exact time to run while providing the video ram address at the same time.

The eeprom takes up the same 16k as the ram but if the VIC isn't addressing something between 0800 and 06fff then the video output needs blanking.

So the code that the VIC sees (at say, 0800 where the first line lives) is a series of nineteen lda #0, which takes 38 cycles and addresses 38 successive video ram locations, and is ended by a jump to the code to handle the line sync. The jmp takes three addresses and takes three clocks which is handy, but it means the 41st video ram address is also output, but when it jumps above 7000 the video output is blanked.

I get a convenient 320 dots across a screen line (instead of the 640 intended) so to keep a reasonably square pixel and also to reduce the memory required I show each line twice for 240 lines vertically.

(There have been a number of iterations and there will no doubt be more, but I think I have the basic idea nailed.)

Is this enough detail at this point?

Neil


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 26, 2023 9:25 pm 
Offline

Joined: Sat Oct 09, 2021 11:21 am
Posts: 718
Location: Texas
barnacle wrote:
Is this enough detail at this point?
Neil


Ok, I think I get it now. The VIC 6502 generates the addresses for the Video RAM, not the video data itself. LDA #$0 just so happens to have 2 bytes if memory, and 2 clock cycles to execute. When the VIC 6502 is trying to access the RAM though, you cut it off and send the RAM output elsewhere to get video signals? Would this then make your VIC 6502 essentially a tightly controlled timer/counter?

I saw you wanted to keep the 1.8432 MHz clock, but that is in no way divisible by the 25.175 MHz VGA clock. So, are the CPU 6502 and the VIC 6502 running at different clock speeds? It doesn't seem so by your pictures, but I could be wrong. You seem to be going for the 640x480 default, given you are ultimately using 320x240 pixels, but the clock speed for that does not match up with any UART clock speed that I know of?

Very interesting concept, it's almost beyond my understanding. I understand it now, I think, but... very interesting concepts :) Thank you for sharing Neil! I'll stay tuned and watch for developments.

Chad


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 27, 2023 6:02 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 988
Location: Potsdam, DE
Yes; the VIC is a tightly timed - by software - video memory access generator, rather than using something like a 6845 to generate the memory addresses. On each line, it executes code from prom that does the required increment each clock in the memory address. If it all works, of course...

You're quite right that the VGA 25MHz clock and the 1.8MHz UART/PH0 clock don't match. However, VGA is an analogue video system; as long as the line syncs arrive at the right frequency (and the field syncs are 525 lines apart!) then it doesn't actually *need* to have 640 dots across the line - as witnessed by e.g. Ben Eater's (and numerous others') simplified VGA outputs. They approach minimalism by using a few wide 'pixels' across a line but by including colour or grayscale; I'm doing it with a much faster pixel though still not full VGA bandwidth and my output is either black or white, no grayscale.

The line timing for a VGA 640x480 display is 800 clocks at 25.175MHz, which comes out at 31.777557100298us(!). The clock period of the 1.8432MHz is 0.54253us; the one divided by the other gives 58.57 clocks per line. Which is a little outside the nominal tolerance for VGA if I use either 58 or 59 clocks per line, but I hope my display can cope with it. An old analogue CRT display would have no issues with it.

Conveniently, there are plenty of crystals and oscillators at 8*1.8432MHz - 14.7456MHz, so that bit is easy.

A thought which occurs to me is that the spec for RS232 is a tolerance of 2% to maintain communications. If I need to make a slight tweak to speed up the pixel clock by a fraction then the change should not affect the RS232 reception. However, that needs a slight oscillator redesign to include a tuning capacitor, which I'd much rather avoid.

Neil

edit: Hmmm, 59 clocks per line would need an 8 times oscillator of 14.85325...MHz; you can get 14.85MHz crystals, and divided down you'd get a baud rate of 116, 016 instead of 115,200; that's 0.7% out and well within RS232 spec.
Or you could just use 25.175MHz as designed, but you'd need to arrange the serial port differently.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 27, 2023 9:41 am 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
To throw my 2 cents into the mix, wouldn't a crystalless UART be a good option? Like the FT240X, or a small microcontroller?
That way you're not limited to a clock that is a multiple of some baud rate (or close to one)


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 27, 2023 10:33 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
In this "6502 as a VGA controller" experiment, I used a 6502 to send data from memory to video display very similar to what you are describing except I've not thought about switching BE to run dual 6502 but ran a single 6502 at 25.175MHz instead. The video output was monochrome 640x480 as you can see on Mar 13 2021 post. I had a 64-macrocell CPLD to help me with logic but it did not have sufficient logic to do fractional divide to generate 1.84MHz serial clock from 25.175MHz, so I just divided 25.175MHz by 14 and the serial protocol seems to handle the 2.5% mismatch very well. The horizontal sync timing needed to be very precise and must be generated even during the video blanking period. It is possible to do it in software, but boy, that was a major pain to deal with. I was fortunate to find sufficient logic in CPLD to implement a hardware horizontal sync counter so software had more freedom during the vertical blanking period. While the vertical blanking period is only 86mS per second, a 25MHz 6502 can perform tasks like a 2MHz 6502 during that short time.
Bill

Edit, I repeated the experiment again with the CPLD trainer which has a larger 128-macrocell CPLD. In that case I did have sufficient logic for a fractional divide to divide 25.175 by 13.5. In both cases the serial port communication had worked perfectly.
viewtopic.php?f=10&t=6974&p=94497&hilit=vga+controller#p94782


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 49 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron