Page 6 of 12
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 2:14 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 2:37 pm
by Chromatix
The LCD will only respond to access cycles in which it is selected. Do you have an address decoder to take care of that?
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 3:24 pm
by Dr Jefyll
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

Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 3:27 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 3:38 pm
by Dr Jefyll
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 4:16 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 4:44 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 6:33 pm
by GARTHWILSON
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.)
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 7:33 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sat Feb 08, 2020 9:05 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Sun Feb 09, 2020 4:17 pm
by JuanGg
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 65
c02. 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
Re: Micro programmed 6502-like CPU
Posted: Mon Feb 10, 2020 5:43 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Tue Feb 11, 2020 1:50 am
by Dr Jefyll
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?
Re: Micro programmed 6502-like CPU
Posted: Tue Feb 11, 2020 3:30 pm
by JuanGg
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
Re: Micro programmed 6502-like CPU
Posted: Tue Feb 11, 2020 6:52 pm
by JuanGg
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