6522 VIA partial shifts?
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
6522 VIA partial shifts?
Can the 6522 shift register do more or less than 8 shifts?
I'm thinking of replacing my 3 chip PS/2 keyboard solution of inverter + two external '595's with a simple software solution:
1) Use the 6522 shift register, mode 011
2) Ignore the IRQ after 8 shifts and just reset it.
3) Instead use T2/PB6 input counting set to 9 counts
4) Read the shift register during the 9 count IRQ, which should mean the start bit has been shifted out but the parity and stop bit hasn't been shiftet in yet == 8 data bits.
5) Reset the shift register after I have what I need and get ready for new data
Any reason this won't work? As far as I know the shift register keeps data until it's shifted out, right?
I'm thinking of replacing my 3 chip PS/2 keyboard solution of inverter + two external '595's with a simple software solution:
1) Use the 6522 shift register, mode 011
2) Ignore the IRQ after 8 shifts and just reset it.
3) Instead use T2/PB6 input counting set to 9 counts
4) Read the shift register during the 9 count IRQ, which should mean the start bit has been shifted out but the parity and stop bit hasn't been shiftet in yet == 8 data bits.
5) Reset the shift register after I have what I need and get ready for new data
Any reason this won't work? As far as I know the shift register keeps data until it's shifted out, right?
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
Re: 6522 VIA partial shifts?
I'm pretty sure it's just a circular buffer. If you don't provide new data, but are using an external clock, it will keep shifting out the last 8 bit pattern you provided. For input if you don't read it in time the oldest bit will be lost when the next bit is shifted in. The interrupts are there to help you know when it's been 8 shifts since you last did something to it, so it's up to you whether you use them or not.
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
gfoot wrote:
I'm pretty sure it's just a circular buffer. If you don't provide new data, but are using an external clock, it will keep shifting out the last 8 bit pattern you provided. For input if you don't read it in time the oldest bit will be lost when the next bit is shifted in. The interrupts are there to help you know when it's been 8 shifts since you last did something to it, so it's up to you whether you use them or not.
At 10-15khz ps/2 clock it shouldn’t be a problem to sample before the data is gone.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
Re: 6522 VIA partial shifts?
The 6526 shift register was used for RS232 in a way like you suggest, to achieve 9600 baud RS232 on a C64 userport (that, with bit banging would only go up to 2400 baud)
For output, it would first output start bit + 7 data bits, plus in a second byte, the 8th data bit and the stop bit(s), with the rest being filled up with 1s.
For input, another input would be used as trigger on the start bit (via NMI), then the timer would be set, and 8 data bits being shifted in based on timer (not on external clock).
For output, it would first output start bit + 7 data bits, plus in a second byte, the 8th data bit and the stop bit(s), with the rest being filled up with 1s.
For input, another input would be used as trigger on the start bit (via NMI), then the timer would be set, and 8 data bits being shifted in based on timer (not on external clock).
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
Re: 6522 VIA partial shifts?
AndersNielsen wrote:
5) Reset the shift register after I have what I need and get ready for new data
Briefly, I had a situation where the entire machine (including the VIA) had had a hardware reset; then there was some code that programmed T1 of the VIA for square wave output on PB7. (It's all part of the boot sequence on this machine.)
I wanted to test an alternative version of the code, and ideally I should've done a hardware reset before running the test. But a hardware reset of just the VIA alone would've been awkward, so instead I settled for simply writing zeros to the ACR. I figured that would put the timer in the same state as that which follows a hardware reset... but I was mistaken. (Sometimes it would work; other times not. Perhaps this had to do with whether PB7 happened to be high or low at the time, but IDK -- I didn't investigate.)
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
fachat wrote:
The 6526 shift register was used for RS232 in a way like you suggest, to achieve 9600 baud RS232 on a C64 userport (that, with bit banging would only go up to 2400 baud)
For output, it would first output start bit + 7 data bits, plus in a second byte, the 8th data bit and the stop bit(s), with the rest being filled up with 1s.
For input, another input would be used as trigger on the start bit (via NMI), then the timer would be set, and 8 data bits being shifted in based on timer (not on external clock).
For output, it would first output start bit + 7 data bits, plus in a second byte, the 8th data bit and the stop bit(s), with the rest being filled up with 1s.
For input, another input would be used as trigger on the start bit (via NMI), then the timer would be set, and 8 data bits being shifted in based on timer (not on external clock).
I guess it’s time to do some tests and see where I can get away with fewest pins and least cpu cycles.
@jeff Reading or writing th SR should both clear the IRQ and I suppose the internal shift counter as well. Must confirm.
Maybe your T1 issue was that you didn’t start it by writing T1CH? (After setting ACR)
I have noticed some fuzzy things for that mode while playing with my tape interface.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
Well... Certainly doesn't work yet. I have the clock signal connected to both CB1 and PB6, and data to CB2
I'm getting seemingly random data - rarely the correct code, sometimes a value that's been shifted too far or too little. Like the code for "O" is $44 - this sometimes comes through as $88 or $22 or $11.
Could this work? Where am I most likely to miss clocks to cause misalignment?
Code: Select all
t2_irq:
lda kbbit
cmp #2
beq count9 ; If we only counted to 2 then reset counter to 9
lda SR1 ; If we counted to 9 then fall through and save SR and reset counter to 2
sta $0B
lda #2
sta kbbit
sta T2CL
lda #0
sta T2CH
beq newcount ; BRA
count9:
lda #9
sta kbbit
sta T2CL
lda #0
sta T2CH
; bit SR1 ; Superfluous?
newcount:
pla
rtiCould this work? Where am I most likely to miss clocks to cause misalignment?
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
Re: 6522 VIA partial shifts?
I don't see anything wrong with your code. I suppose there is some more to the interrupt service routine, but it would have to be rather long to interfere with receiving the scan code, unless you're running at 1 MHz, where it could start to get tight. Unfortunately, this method doesn't allow you to check the start, stop and parity bits. I save all bits to a circular buffer and use those to keep things in sync. There should be sufficient time between keystrokes to process it. I've offloaded this to an ATtiny85 (an 8-pin DIP) and only send the final ascii byte to the 65c22 shift register.
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
tmr4 wrote:
I don't see anything wrong with your code. I suppose there is some more to the interrupt service routine, but it would have to be rather long to interfere with receiving the scan code, unless you're running at 1 MHz, where it could start to get tight. Unfortunately, this method doesn't allow you to check the start, stop and parity bits. I save all bits to a circular buffer and use those to keep things in sync. There should be sufficient time between keystrokes to process it. I've offloaded this to an ATtiny85 (an 8-pin DIP) and only send the final ascii byte to the 65c22 shift register.
viewtopic.php?t=5058 had some suggestions - including Dieters/Eaters version I’m using now..
I’m tempted to use the shift register irq and then simply block in the ISR until the SR changes and I have the final bit… Probably a bad idea.
Or fetch 8 bits in the ISR and the last one in the main loop.. haven’t thought that one through.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
Re: 6522 VIA partial shifts?
Are you sure about which edges trigger shifting and counting? Can you show the 6522 initialisation code, especially ACR, PCR, and IER setup, plus how you are kicking off the read?
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: 6522 VIA partial shifts?
gfoot wrote:
Are you sure about which edges trigger shifting and counting? Can you show the 6522 initialisation code, especially ACR, PCR, and IER setup, plus how you are kicking off the read?
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
gfoot wrote:
Are you sure about which edges trigger shifting and counting? Can you show the 6522 initialisation code, especially ACR, PCR, and IER setup, plus how you are kicking off the read?
Enters IRQ SR like this:
Code: Select all
;IFR is IRQ Tl T2 CBl CB2 SR CA1 CA2
irq:
pha
lda #%00100000 ; We need T2 to fire super fast, so we check it first.;
and IFR
bne t2_irq
Code: Select all
; After reset
lda #$01 ; CA1 positive active edge (Testing with the keyboard connected the "old" way)
sta PCR
lda #%11100010 ; Set CA1 + T2 + T1
sta IER
LDA #%01101100
STA ACR ; T1 continuous, T2 count, PB7 disabled, Shift In External
lda #9
sta kbbit
lda #9
sta T2CL
lda #0
sta T2CH
bit SR1
ACR should be mode 011
IER has T1, T2 and CA1 enabled.
I don't think it's a problem that the kb is also connected the old way - that just reads ORA on CA1 high edge IRQ. (Triggers well after kb is done clocking). My T1 timekeeping triggers every 7998 clocks.
@GarthWilson
The edge could have something to say, but then I would expect to see the same data when pressing a key, but simply incorrect? Also - if the edge is incorrect I would assume changing the PB6 count would be sufficient... Maybe.. Another thing to watch out for.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
GARTHWILSON wrote:
gfoot wrote:
Are you sure about which edges trigger shifting and counting? Can you show the 6522 initialisation code, especially ACR, PCR, and IER setup, plus how you are kicking off the read?
"Note that data is shifted during the first system clock cycle following the leading edge of the CB1 shift pulse. For this reason, data must be held stable during the first full cycle following CB1 going high."
The illustration then shows that data is shifted at point A - which is the second phi2 low period after the CB1 rising edge. Data is certainly still valid there. But maybe the PB6 count should be 10 to be sure 9 bits have been shifted.. Maybe?
Edit: After staring at a timing diagram for 10 minutes I’m pretty certain I should be sampling the SR after 10 PB6 low edge counts == 9 shifts.
Testing that tomorrow.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
- AndersNielsen
- Posts: 185
- Joined: 26 Dec 2021
- Contact:
Re: 6522 VIA partial shifts?
Mmmkaaay... This is not as easy as I would've hoped.
PS/2 is LSB first, 6522 Shift register is MSB first - from mode 010, that I missed before:
I noticed because I tried the SR IRQ route instead and got confused if I should use ROL or ROR for shifting in the last bit. ROL it is.
The best idea to get this approach working is to bit juggle the bits to the correct order - inline for speed.
So this is my current attempt ISR for the shift register:
It actually kind of works... Sometimes... I'm getting $44 half the time, but also a lot of $22 and $24. Other scan codes seem to confirm that it's kind of working.. The dreaded 011 mode bug is looming though. Was really hoping I didn't have to bring out extra hardware, but of course I have a '74 somewhere..
Currently I'm re-enabling the shift register when my cursor is blinking
Edit:
Since I had the MSB/LSB error before, I'll go back to the PB6 counting method again - reversing the shift register mig be what was missing.
Edit2: I finally did the sensible thing and used an output pin for debugging and connected my scope to that and the clock.. It's certainly not sampling the SR at the right time. It's basically rotating right every time I press a key.
Edit3: This actually seems to work. My debug pin tells me it's sampling SR right before the 10th rising edge. (Which is later than what I would expect with PB6 count being set to 9 and not 10)
In the main loop I reset the T2 counter every half second to kill the creeping framing errors.
Time to try a 74'74.
PS/2 is LSB first, 6522 Shift register is MSB first - from mode 010, that I missed before:
Quote:
Data is shifted first into bit 0 and is then shifted into the next higher
order bit of the shift register on the trailing edge of each clock pulse.
order bit of the shift register on the trailing edge of each clock pulse.
The best idea to get this approach working is to bit juggle the bits to the correct order - inline for speed.
So this is my current attempt ISR for the shift register:
Code: Select all
lda SR1
sta $0B
getlastbit:
lda SR1
cmp $0b
beq getlastbit
LDA #%01000000 ; Let's disable the shift register after the last bit and reenable in main loop after half a second (for debugging)
STA ACR ; T1 continuous - disable T2 and Shift register
and #1
beq notset
sec
bcs rotatelastbit ; BRA
notset:
clc
rotatelastbit:
lda $0b
rol
sta $0b ; LSB is in MSB :/
; I could probably do this bit shuffling in the main loop I guess
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
pla
rti
Currently I'm re-enabling the shift register when my cursor is blinking
Edit:
Since I had the MSB/LSB error before, I'll go back to the PB6 counting method again - reversing the shift register mig be what was missing.
Edit2: I finally did the sensible thing and used an output pin for debugging and connected my scope to that and the clock.. It's certainly not sampling the SR at the right time. It's basically rotating right every time I press a key.
Edit3: This actually seems to work. My debug pin tells me it's sampling SR right before the 10th rising edge. (Which is later than what I would expect with PB6 count being set to 9 and not 10)
Code: Select all
t2_irq:
lda kbbit
cmp #2
beq count10 ; If we only counted to 2 then reset counter to 9
lda SR1 ; If we counted to 10 then fall through and save SR and reset counter to 2
; T1 continuous - disable Shift register
sta $0b ; LSB is in MSB :/
lda #$81
sta $5000 ; Ouput only register debug
LDA #%01100000
STA ACR
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
rol $0b ; MSB to C
ror $0c ; C to MSB
lda #2
sta kbbit
sta T2CL
lda #0
sta T2CH
lda #1
sta $5000 ; OOR debug
beq newcount ; BRA
count10:
LDA #%01101100
STA ACR ; T1+T2, reenable Shift register
lda #9
sta kbbit
sta T2CL
lda #0
sta T2CH
; bit SR1 ; Superfluous?
newcount:
pla
rtiTime to try a 74'74.
---
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
New new new new new video out! Serial Bootloader for my 65uino
Also, check out: I2C on a 6502 Single Board Computer
and Complete hardware overview of my 6502 SBC R1
Re: 6522 VIA partial shifts?
If you must juggle bits, avoid doing it in the ISR if at all possible. Do it in the code putting it into the buffer or retrieving it from the buffer instead. Try to make your ISR as short and fast as you can.