6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 8:21 pm

All times are UTC




Post new topic Reply to topic  [ 176 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 12  Next
Author Message
PostPosted: Sat Feb 08, 2020 2:14 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
More issues

I have been able to initialize the LCD and to write some characters to it. The thing is that consecutive characters have spaces between them.

The cause is that the LCD module increments its address counter when either writing or reading from it. After my CPU writes the relevant data, address registers remain unchanged for some clock cycles (with R/W high), so the LCD module thinks that it's being read, and increments its internal address counter, thus the spaces.

Would it be this way on a genuine 6502? I am using this setup: http://www.6502.org/mini-projects/optrexlcd/lcd.htm, and it makes no mention of this.

Note: I am ignoring the LCD module's busy flag as I'm running the clock at very low speeds (below 1khz).
Juan


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 2:37 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
The LCD will only respond to access cycles in which it is selected. Do you have an address decoder to take care of that?


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 3:24 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
JuanGg wrote:
After my CPU writes the relevant data, address registers remain unchanged for some clock cycles (with R/W high), so the LCD module thinks that it's being read
If I understand you, the LCD is being read, even though the action is unintended and the data it places on its data bus pins is ignored. And, a read alters the state of the device (by incrementing the counter). This makes your LCD different from most I/O devices (and from memory), which can tolerate unplanned reads and suffer no effect. The LCD is a read sensitive device, and unwanted aka spurious reads are sometimes called destructive reads.

Genuine 65xx CPU's do in some cases generate spurious reads that can affect read sensitive devices, although newer chips such as the the CMOS version (65C02) and the 65C816 have features that help reduce the problem. For example, on the 'C02, unplanned reads of the addressed device are in almost all cases replaced by reads of some other location which can safely be assumed not to be read sensitive. The address held in PC is an example of this.

In a moment I'll link to further information. :)

edit: misc. silly typos :roll:

_________________
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 Feb 08, 2020 4:39 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 3:27 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
Chromatix wrote:
The LCD will only respond to access cycles in which it is selected. Do you have an address decoder to take care of that?


Yes I do. The problem is that the LCD remains enabled while the address on the address registers does not change (three to four clock cycles after the write is performed). On those cycles, when the LCD is still enabled, but I'm not writing to it, it thinks it's being read and moves the cursor each time.
Juan


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 3:38 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
In this post you'll find a document which lists all instances of "dead" (ie, unused) bus cycles on 6502 and 65C02. It's during these unused cycles that spurious reads may occur. For info on the 65C02 "fix" to reduce the severity of spurious reads refer to Note 7 re: "PBA." Very often it's the address in PC which appears on the bus. But it's more exact to say the address used is the Previous Bus Address (PBA). Often the previous bus address is PC, but not always.

Edit: perhaps your project could be altered so the addresses that appear during unused bus cycles are all safe (ie, not read-sensitive) addresses. That's the 'C02 approach.

But it may be easier to use an approach like that of the 65C816, which provides an output signal (VDA) which is low during unused bus cycles. Having created such a signal, you would make it an input to the decoder that tells the LCD when it's being selected. This would exclude the unused bus cycles (during which the spurious reads occur). In response to a read or write instruction, your VDA signal would go true for one cycle only. Subsequent cycles would not select the LCD even though its address remains on the bus

-- 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: Sat Feb 08, 2020 4:16 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
Dr Jefyll wrote:
If I understand you, the LCD is being read, even though the action is unintended and the data it places on its data bus pins is ignored. And, a read alters the state of the device (by incrementing the counter). This makes your LCD different from most I/O registers (and from memory), which can tolerate unplanned reads and suffer no effect. The LCD is a read sensitive device, and unwanted aka spurious reads are sometimes called destructive reads.

Genuine 65xx CPU's do in some cases generate spurious reads that can affect read sensitive devices, although newer chips such as the the CMOS version (65C02) and the 65C816 have features that help reduce the problem. For example, on the 'C02, unplanned read cycles of the addressed device are in almost all cases replaced by reads of some other location which can safely be assumed not to be read sensitive. The address held in PC is an example of this.

In a moment I'll link to further information. :)


Precisely that :). I thought about changing the microcode so after reading or writing it would clear the High address register (so spurious reads would land in RAM), but certain instructions store the data straight into that same register, so that wouldn't work.

Or I could bring out separate Read and Write lines (which I have available), but it would no longer be a 6502 (As if it was one now...)
Other solutions that I can think of are putting some buffers or latches after the address registers so they go to 0 when not reading or writing. But I have no space left for that on the corresponding card.
Or even gating PHI2 so it remains high unless reading or writing...
Driving the LCD with a 6522 VIA would work as well. (I have some fake ones laying around, not sure if I want to even know if they work)

A quick and dirty solution is gating the enable pin of the LCD with the inverse of the R/W line. That way the LCD can only be written to (may limit certain functionality, mainly reading the "busy" flag, so I would have to use some sort of delay loop to meet timing requirements at higher clock speeds), but there are no spurious reads to worry about. (I've tried it and it works).

Attached is a screenshot from a logic analyzer just to clarify. A0 is a register select for the LCD. Four pulses can be seen on the enable line (output from the address decoder anded with PHI2) Writes are performed on the second falling edge.

Just some thoughts.
Juan


Attachments:
LCD enable.JPG
LCD enable.JPG [ 40.24 KiB | Viewed 3539 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 4:44 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
Dr Jefyll wrote:
In this post you'll find a document which lists all instances of "dead" (ie, unused) bus cycles on 6502 and 65C02. It's during these unused cycles that spurious reads may occur. For info on the 65C02 "fix" to reduce the severity of spurious reads refer to Note 7 re: "PBA." Very often it's the address in PC which appears on the bus. But it's more exact to say the address used is the Previous Bus Address (PBA). Often the previous bus address is PC, but not always.

Edit: perhaps your project could be altered so the addresses that appear during unused bus cycles are all safe (ie, not read-sensitive) addresses. That's the 'C02 approach.

But it may be easier to use an approach like that of the 65C816, which provides an output signal (VDA) which is low during unused bus cycles. Having created such a signal, you would make it an input to the decoder that tells the LCD when it's being selected. This would exclude the unused bus cycles (during which the spurious reads occur). In response to a read or write instruction, your VDA signal would go true for one cycle only. Subsequent cycles would not select the LCD even though its address remains on the bus

-- Jeff


Making addresses safe on unused cycles would require additional hardware for which I have no room for (short of adding daughter boards to my CPU cards) So i think I will go with the 65816 approach as you suggest. I already have a Valid Address signal available (though active low), and I can bring it out trough one of the N.C pins on the 6502 pinout. That signal may come in handy for future peripherals.
Juan


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 6:33 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Note that Chris Ward's page you reference says "do function set 4 times" in the initialization code.  There's a reason for this, but you're not doing it.  The 6502 Primer's displays page has sample LCD code linked, and I do it three times there.  The RSTLCD routine there is necessary to set the LCD up to operate, and doing it reliably is the part that is elusive in most of the data sheets.  We finally got it from an applications engineer after wasting a lot of time, so take heed!  There are required delays there, the longest being over 1.6ms near the end of the RSTLCD routine.  Actually, the code is in several forms there, and I see I have 5ms elsewhere.  I don't remember the reason for that.  If you're really running at 1kHz, you're probably meeting it ok; but it might be worth checking.  (Once it's set up, you don't need the delays to be anywhere near that long.)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 7:33 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
GARTHWILSON wrote:
Note that Chris Ward's page you reference says "do function set 4 times" in the initialization code. There's a reason for this, but you're not doing it. The 6502 Primer's displays page has sample LCD code linked, and I do it three times there. The RSTLCD routine there is necessary to set the LCD up to operate, and doing it reliably is the part that is elusive in most of the data sheets. We finally got it from an applications engineer after wasting a lot of time, so take heed! There are required delays there, the longest being over 1.6ms near the end of the RSTLCD routine. Actually, the code is in several forms there, and I see I have 5ms elsewhere. I don't remember the reason for that. If you're really running at 1kHz, you're probably meeting it ok; but it might be worth checking. (Once it's set up, you don't need the delays to be anywhere near that long.)


I've tried initializing it several times as in the code you linked, and it behaves the same way. Actually in the datasheet it says that it should decrement the address counter when being read (but in practice it is incrementing it?). I'm running it really slow just for testing, so delays should be met.
Juan


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 08, 2020 9:05 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
Regarding address decoding, this is what I'm thinking:

-32K RAM 0000-7FFF.

-I/O 8000-9FFF. LCD at 9E00-9FFF, see attached.

-8K "Cartridge" ROM A000-BFFF (32K ROM, 8K selectable with dip switches).

-16K ROM C000-FFFF.

There are always three or less gate delays, and I could easily relocate the LCD with spare inverters. There is also 1/2 of a 74HC139 available for anything else that may go on the top card. VA is the hypothetical "valid address" pin.

Further address decoding will be on other cards, next to the relevant I/O, independent from the first card.
Any suggestions are welcome. Pardon the crudity of the schematic.

EDIT: 74HC139 has active-low outputs, and the LCD has active high. So using two AND gates resulted in less complexity. Now the LCD spans from $9C00 to 9FFF. Updated the schematic. I've built it up and works perfectly.
The empty ZIF socket and the dip switches are placeholders for now. I'll add the extra ROM later, or remove it altogether.

Juan


Attachments:
Hello_world.jpg
Hello_world.jpg [ 223.65 KiB | Viewed 3493 times ]
Address_decodingV2.jpg
Address_decodingV2.jpg [ 95.46 KiB | Viewed 3493 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 09, 2020 4:17 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
GARTHWILSON wrote:
Note that Chris Ward's page you reference says "do function set 4 times" in the initialization code. There's a reason for this, but you're not doing it. The 6502 Primer's displays page has sample LCD code linked, and I do it three times there. The RSTLCD routine there is necessary to set the LCD up to operate, and doing it reliably is the part that is elusive in most of the data sheets. We finally got it from an applications engineer after wasting a lot of time, so take heed! There are required delays there, the longest being over 1.6ms near the end of the RSTLCD routine. Actually, the code is in several forms there, and I see I have 5ms elsewhere. I don't remember the reason for that. If you're really running at 1kHz, you're probably meeting it ok; but it might be worth checking. (Once it's set up, you don't need the delays to be anywhere near that long.)


In the article you linked, you say you used a 65c02. As Dr Jefyll said, the CMOS version seems to default to safe addresses during unused cycles, so you would not have had any issues with spurious reads. So I suppose I had to add an extra 'valid address' pin in the end.

I've now gotten to a point where I can do some work on the software side, get myself familiar with 6502 assembly, macros etc.
That was my objective. Tomorrow I'll become a full-time university student again, so I won't have as much time left for this. Thanks everybody for your help.

Even though, I am thinking of adding a PS/2 keyboard interface. I'll try designing something similar to what's proposed here (towards the bottom). I don't want to use a microcontroller or a 6522 as of now.
Juan


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 10, 2020 5:43 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
This is a simple PS/2 interface I've designed. Down to four additional ICs, some passives and a transistor, which is just enough to fill the space left on the memory card. One could repace the 555 timers with gates (B), as they are being used as a Schmitt trigger and RS latch respectively. I've tried it out on a breadboard and seems to work fine.

Each time a frame is received from the keyboard, an interrupt is triggered. When the key code is read from the appropriate address, the interrupt line is released. Not checking parity, as that would add additional complexity.
Juan


Attachments:
PS2KeyboardInterface.jpeg
PS2KeyboardInterface.jpeg [ 120.35 KiB | Viewed 3445 times ]
Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 11, 2020 1:50 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
JuanGg wrote:
One could repace the 555 timers with gates (B), as they are being used as a Schmitt trigger and RS latch respectively. I've tried it out on a breadboard and seems to work fine.
A 74HC123 may be more appropriate than 555's or gates, and would probably eliminate the R-C network and diode-R-C network shown in your diagram. But it's understandable if you prefer to stick with the circuit you've already gotten working.

Unlike the 'HC221, the 'HC123 is "retriggerable." Once triggered, the output pulse width may be extended by retriggering the inputs.

-- Jeff

http://www.ti.com/lit/ds/symlink/cd74hc123.pdf

ETA: it seems odd that two shift-registers would be required. Might you be able to manage with just one?

_________________
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: Tue Feb 11, 2020 3:30 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
Dr Jefyll wrote:
A 74HC123 may be more appropriate than 555's or gates, and would probably eliminate the R-C network and diode-R-C network shown in your diagram. But it's understandable if you prefer to stick with the circuit you've already gotten working.

Unlike the 'HC221, the 'HC123 is "retriggerable." Once triggered, the output pulse width may be extended by retriggering the inputs.

-- Jeff

http://www.ti.com/lit/ds/symlink/cd74hc123.pdf

ETA: it seems odd that two shift-registers would be required. Might you be able to manage with just one?


I don't have any 'HC123s at hand (I didn't even know about them). But I will add them to the list so I get some on my next big order.
I'm not too keen on relying on RC networks for timing, but I think the margins here are somehow broad, so it should be ok.

Regarding the shift registers, a PS/2 data frame has 11 bits: Start, 8 x Data, Parity and Stop. So to get only the 8 bit data, I would have to prevent the last two bits from shifting in. I've thought about latching a single '595 after nine clock pulses, but that would require something like a counter and some gates. So chaining an additional shift register seemed the simplest approach to me. I can just connect to the data bus the bits I need. I'll be happy to find out about alternative solutions though.
Juan


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 11, 2020 6:52 pm 
Offline
User avatar

Joined: Mon Nov 04, 2019 4:53 pm
Posts: 103
Location: Spain
I've built the keyboard interface on the top card and seems to work as expected. Interrupts themselves are not working perfectly, particularly at higher clock speeds, I also have to change the microcode for RTI (I forgot to re-enable interrupts here). I'll have to take a further look at it.

Just noticed that in case I connect more devices to the IRQ line, I have no way of knowing whether if the keyboard caused the interrupt or it was something else. I'll see if I can devise a way of clearing the registers after they have been read, or maybe enable another memory location to display if the keyboard is waiting to be serviced... But that would require additional hardware for which I barely have room for.
I may take out the additional ZIF socket for a future "cartridge rom" and put some and gates and a 'HC245 bus transceiver, which would do.

I could also check all other hypothetical future devices first, and if none of them were, then it's the keyboard, but it doesn't seem right.
Juan


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 176 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 12  Next

All times are UTC


Who is online

Users browsing this forum: BigEd and 13 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: