6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Apr 28, 2024 10:31 pm

All times are UTC




Post new topic Reply to topic  [ 33 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Sat Dec 09, 2023 1:34 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Jeff,
You are right that ROL SerData is no different than BIT SerData in term of amount of time available for RC to decay to the correct value. I've replaced ROL SerData with BIT SerData and it still work just fine at 25MHz. I can not observe with a scope, however, because the added scope capacitance (13pF) is sufficient to break the hardware from working.

Switching to lower frequency, I can see with scope that the time constant, tau, from initial 4V to 1.5V (37% of 4V) is 108nS so the capacitance is calculated at 45pF, scope probe included. Without the probe it is 32pF or tau of 77nS. I know the voltage is falling rapidly and it only needs to cross over the logic threshold which is probably 2.5V, but 40nS is still very short amount of time to sample signal with 77nS time constant.

Something is still not quite right...
Bill
Edit, break out my scientific calculator and found the time from 4V to 2.5V with tau of 77nS is 36nS, just barely made it.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 09, 2023 1:52 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
plasmo wrote:
Perhaps I should’ve used LDA SerData,X instruction?
Yes, I think you're on the right track with this idea. Arrange things so the ,X indexing is sure to result in a page crossing and thus an extra cycle (ie, two reads in a row as the instruction concludes). It'll be the second read which determines the outcome.

And of course we don't want other devices driving the bus, just the resistor, so you'll wanna consider both addresses that the instruction generates. The first will be as if X=0 [edit: incorrect; see below]; then the final cycle will have the fully baked address.

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Sat Dec 09, 2023 5:13 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 09, 2023 4:47 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Dr Jefyll wrote:
plasmo wrote:
Perhaps I should’ve used LDA SerData,X instruction?
Yes, I think you're on the right track with this idea. Arrange things so the ,X indexing is sure to result in a page crossing and thus an extra cycle (ie, two reads in a row as the instruction concludes). It'll be the second read which determines the outcome.

I did a quick test with the instruction

LDA $F008,X
where X is 0xFF

It took 5 clocks to execute; the 5th clock is address $F107 ($F008+$FF) as expected, but the 4th clock address is still in the ROM area where data bus is still driven by ROM output enable. So I still have only one clock period where data is driven by the resistor. The dummy cycle appears to be address of next instruction in ROM.

Any other instruction I can try?
Bill


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 09, 2023 5:11 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
plasmo wrote:
The dummy cycle appears to be address of next instruction in ROM.
Doh! You're right. Somehow I was thinking of NMOS, and failed to consider the enhancements incorporated in the 'C02.
Attachment:
'C02 enhancements.png
'C02 enhancements.png [ 21.05 KiB | Viewed 5395 times ]

Quote:
Any other instruction I can try?
Nothing occurs to me at the moment, instruction-wise. But maybe there's a cheap hardware hack that'd help... For example, something that'd briefly pulse RDY low as we're reading the resistor. Hm...

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 10, 2023 7:08 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
Alright, I have several ideas, and some of them don't smell very nice although they could perhaps be made to work! :P I can't fully address the details right now, but there are three basic strategies.

One strategy we're already discussing is to add more time to the read cycle that inputs the RX bit, thus giving the RC a longer period in which to resolve. For example, to briefly pulse RDY low, we could have a resistor pulling RDY high but also have a capacitor that ties MLB to RDY. With luck, a 3-cycle low pulse on MLB will produce a 1-cycle (approx) low pulse on RDY. Among other downsides, it'd be obligatory for the serial input code to use only RMW instructions to read RX. Also, every RMW instruction would get slowed down, even if it's in the application code (as opposed to the serial input code).

Another strategy perhaps worth considering is to partially "precharge" (actually discharge) the RC so it'll resolve more quickly. As is, data line D7 will always be high in the cycle before the RC curve begins. That's because the final operand byte is being read in that cycle, and bit7 of that operand ($FF) is a 1. So, there's a huge asymmetry. If RX is 1 then no time at all is required for the RC to resolve, but the time required is very substantial if RX is a 0, because the capacitance needs to be dragged from a 1 down to just below 50% of Vcc (the transition point of the C02's inputs). Off the top of my head -- and this is dicey -- I wonder if the CPU's (presently unused) PHI2O output could, by means of a couple of diodes acting as a zener, pull data line d7 down to roughly 50% during the first half of the cycle. Ideally (!), the diodes will instantly turn off in the 2nd half of the cycle, and the RC curve now has only to rise slightly above or slightly below 50%. I have misgivings, but perhaps this or a similar scheme could be made to work!

The third strategy is to change the means by which RX is read. Presently it's memory mapped, but instead it'd also be possible to channel RX into the SOB input. I picture a gate (or a gate equivalent, using just a resistor and a diode) that feeds SOB with the logical OR of RX and MLB. The program clears the V flag, does a RMW instruction, then conditionally branches on the state of V.

But my favorite proposal uses RX as an address input to the PLD/ROM, which would contain TWO almost identical programs... and the 'C02 would routinely "change horses in midstream" between the two programs as the data comes in. (It's a trick I first used decades ago; see the "slightly OT" paragraphs in this post.) As noted, the programs would be almost identical. But here and there, one will have an instruction that says, "trust me -- no need to test anything; just shift in a 1" and the other sequence will say, "just shift in a 0."

Each of the programs would be less than 32 bytes, so IIUC there will no longer be any need to feed A5 to the PLD/ROM. That gains us an extra input pin, one to which RX can be connected. :)

RX needs to be synchronized to the CPU clock (otherwise there's be a risk the ROM output may be in flux when Phi2 falls), and that means employing one of the flipflops in the PLD. And AFAICT that costs us another pin, because (unlike some PLDs) the 22V10 can't feed both the pin and the Q of the pin's macrocell back into the interconnection matrix.

But it's possible to scrounge another pin if we simply cease to fed A11 to the PLD. This negatively impacts the memory map. There can still be two chunks carved out of the top of the space, but instead of each chunk being $800 in size, each will be $1000 in size. :|

Is that too high a price for opening the door to higher clock rates? It depends one's priorities, so there's no single "right" answer. But IMO this solution is much cleaner than any of the others I've mentioned.

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 11, 2023 12:12 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Lots of neat ideas to consider. I've not thought about using 6502's signals like MLB, SOB, and PHI2O. Switching 2 banks of program based on RX input is a very neat idea. Yes, RX definitely needs to be synchronous to 6502 clock for that to work, but it is one worth thinking more about.

I think biasing the data7 to mid-point with clock is a good idea; it precharge the data line during one phase of clock then relinquish the drive during the sampling phase. I was thinking about bus termination scheme in VME bus, but this seems a simpler solution.

The same bit-bang solution needs to exist in ROM during initial bootstrapping as well as in RAM once code is loaded and running in RAM. So when I think about adding features into 22V10, I also need to think about how to do that in RAM. They can be different solutions; ROM code is single-use so "craziness" is tolerated; RAM code is generalized solution but with more resources available to it. I'm thinking about use of RX-generated interrupt in RAM code so the software doesn't have to sample RX all the time.

I can also brute-force it by lowering the resistor between RX and data7. 25MHz is achieved with 2.4K resistor which doesn't sound too scary considering the drive capability of RAM, 22V10, and W65C02. 1K should gives lots of margin and probably possible with current set of parts. The resistor can be higher value for slower design. I'm thinking of 24MHz @115200 that also works with 4MHz R65C02 @ 19.2K, but the resistor needs to change.

I'm currently working on a similar Z80 implementation based on my experience that thinking about out-of-box ideas on a completely different processor may stumble on a solution to previous problem. I thought it may be interesting to design a pc board that can accommodate both Z80 and 6502.
Bill


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 11, 2023 12:14 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
Quote:
I can also brute-force it by lowering the resistor between RX and data7.
Yeah, that's really not such a bad solution -- not too scary, as you say.

And biasing D7 to the mid-point is an idea I hesitated to even mention. The goal is sound, but diodes don't switch instantly (due to stored charge, AIUI) and they also have capacitance.. and I don't know if those factors are of sufficient magnitude to upset the apple cart.

BTW, the schematic seems to show the oscillator feeding directly to both the PLD clock and the CPU PHi2 input. That seems odd to me, but maybe it's alright for the present setup. However, my "two programs" idea will certainly need one of those clocks to be inverted (in order that the PLD clock will see a rising edge at the beginning of a CPU cycle when Phi2 falls).

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 24, 2023 4:00 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Since I'm already bit-banging the serial transmitter, I thought I can add another function to the serial transmitter by bit-banging it at much higher frequency (800KHz) to drive a panel of WS2812 LEDs. The processor is running at 25MHz so it is not too hard to bit-bang data out at 800KHz. So I connect VCC, Ground, and Muntz65's serial Transmit to the panel's 3-wire connector. Serial port potentially may see some gibberish data, but since WS2812 retains the data (i.e., does not need to be driven repeatedly with the same data), it will be just a momentary gibberish. The color data for 8x8 panel is 192 bytes and transmitted in under 2 milliseconds. For this particular Christmas tree pattern, the serial terminal didn't see any printable gibberish.

Merry Christmas!
Bill


Attachments:
DSC_75171223.jpg
DSC_75171223.jpg [ 1.44 MiB | Viewed 4148 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 24, 2023 6:53 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Either it's christmas, or the lift[0] is going up :mrgreen:

Neil

[0] aka elevator


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 29, 2023 3:29 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
The motivation for running W65C02 at 25.175MHz is the desire to beam racing the VGA display. The idea is designating an area in memory as video memory where a screenful of VGA graphic data are stored. The data are monochrome 640x480 pixels. 640 pixels in a horizontal line is represented by 80 bytes so total memory size is 80x480 or 38.4KB. Hardware implemented in 22V10 monitors the memory such that accessing the video memory cause graphical data to be loaded into 8-bit shift register; but accessing non-video memory causes the data to shift out at 25.175MHz.

During the active video phase, W6502 is running a tight loop that takes exactly 8 clocks to read a byte of data in the video memory to keep up with data shifting out to VGA display. During the horizontal blanking period W65C02 writes to the horizontal sync register and do simple housekeeping task. During the vertical blanking period W65C02 writes to vertical sync register and have more time to process graphic data before starting of next video frame.

22V10 has two more outputs for horizontal sync and vertical sync so in theory software can bit-bang the horizontal sync and vertical sync, but horizontal sync needs to be generated very precisely ALL.THE.TIME, even during vertical blanking period. This is a heavy burden on software so it is highly desirable to have hardware horizontal sync generator that generates horizontal sync pulse as well as an interrupt to W65C02.

I have done the above with a modified CRC65. I'm revisiting it with BB65 with additional hardware implemented in 22V10 and hope to take it further.

Bill


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 01, 2024 12:50 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Here is the bare-bone 6502 with two 22V10 added to work as a 60Hz 640x480 monochrome VGA controller. The memory space is partitioned into program space from $0 to $3FFF and graphic memory from $4000-$DFFF. One of the 22V10 is a loadable shift register that load & shift data read from the graphic memory area to the RGB output of the VGA connector. It also has a writable register that serves as vertical sync output. The other 22V10 is a hardware horizontal sync generator that output fixed 31.5KHz pulse to VGA HSync output.

This is the 8-clock code that read data from the graphic memory region, repeated 80 times. To avoid crossing page boundary which will cost an additional clock for LDA ($b0),y instruction, the 80-byte row data is packed 3 rows per page, so last 16 bytes of every page in graphic memory area are not used.
Code:
   LDA ($b0),y
   INY
   .byte 3      ;this is one cycle NOP

During active video phase, the 25.175MHz 6502 is continuously reading row data to feed the shift register. At end of each row, it executes software wait waiting for interrupt from the horizontal sync pulse. It reads 80x480=38400 bytes 60 times a second so there are no time for other tasks during the active video phase. At the end of a video frame there is about 1.5mS vertical retrace period where only VGA task is generating the vertical sync pulse so there are time to perform other tasks. 90% of time the 6502 is a dedicated VGA controller, but 10% of the time it is a general purpose 2MHz-ish 6502 computer

This first post shows the prototype hardware and 22V10 equations. I'll followed up with schematic, display software and the resulting video image in next post.

Bill


Attachments:
BB65_prototype_VGA_controller_HSYNC.zip [1.24 KiB]
Downloaded 13 times
BB65_prototype_VGA_controller_shift8Vsync.zip [880 Bytes]
Downloaded 13 times
DSC_75301231.jpg
DSC_75301231.jpg [ 1.23 MiB | Viewed 3918 times ]
DSC_75311231.jpg
DSC_75311231.jpg [ 1.2 MiB | Viewed 3918 times ]
Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 01, 2024 4:25 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
This image demonstrates the barebone 6502 VGA controller in action. An image file is first loaded in $4A00-$DFFF and the attached 'VGA6502.hex' is loaded in $1000 and run. VGA6502 displays data from $4000-$DFFF; it also has a task running during vertical retrace periods that unpack the original image file, which is a raw image file, into three blocks of 80-byte data per 256-byte page. That process took 3-5 seconds to run so I can see a jumbled image gradually assembled into the image shown.

This is a barebone implementation of VGA. There are a number of things I don't like:
* one 22V10 output is driving three RGB inputs, so it is overloaded and the display is not bright enough.
* Need to add a single-gate inverter to invert clock because data must be latched on the falling edge of clock. I tried 6502's PHI1O, but it is flaky; I think it is too slow to latch in data before they changed.
* Need to decode the VSync register better. I think I'll shuffle the functions between the two 22V10 to get better better address decode for VSync.
* I need to tweak the software to get better front/back porch for the horizontal sync.
Bill


Attachments:
DSC_75321231.jpg
DSC_75321231.jpg [ 1.31 MiB | Viewed 3892 times ]
BB65_PROTO_VGA_CONTROLLER_scm.pdf [19.9 KiB]
Downloaded 18 times
BB65VGA_controller_VGA6502.zip [2.97 KiB]
Downloaded 17 times
Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 01, 2024 11:59 am 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Very neat. Note:

Code:
Field D = [ D7..0 ];
Field S = [ S7..0 ];
Field nS = [ S6..0, 0 ]; /* next S */

S.d = nS # D & VGAload;
S.[ ar, sp ] = 'b'0; /* I think this works */

That's from memory so may have mistakes, but I've done things like that before to make shift registers so it should be close to working!

plasmo wrote:
* one 22V10 output is driving three RGB inputs, so it is overloaded and the display is not bright enough

Unless you've already calculated it, I don't think that's the cause. 220 is already a bit of a low value for the resistor. More likely, you're accessing video RAM during the blanking interval (e.g. to trigger the vsync?) and causing data to be output as a side effect. The monitor uses the levels during blanking to decide what the black level is overall, so it's important to output solid black there.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 01, 2024 5:40 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1399
Location: Scotland
plasmo wrote:
This image demonstrates the barebone 6502 VGA controller in action.


With very nice copyright free images of Mickey and Minnie... Well done!

Cheers,

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 01, 2024 5:49 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
I thought those two were still in copyright? Steamboat Willie is safe, though... now Disney has screwed up copyright for any sane person who doesn't happen to be an apparently immortal corporation.

Neil


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 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: