6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 23, 2024 5:15 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Thu Jun 30, 2022 3:53 am 
Offline

Joined: Tue Feb 21, 2017 8:32 pm
Posts: 38
Hey Guys, you have all been so helpful in the past I was wondering if you could help me with an issue im experiencing with the 6522. I am trying to use Handshake mode on PA - Specifically testing with Write Handshake at the moment.

Whenever I present Data on PA, the 6522 Pulls CA2 Low as expected. My microcontroller receives this interrupt and grabs the data and responds with pulling CA1 Low. The Interrupt is registered on the 6502 and is processed - but it is not clearing CA2 (Data Ready) state on the 6522 which if I am reading the datasheet correctly it should automatically. The IRQ flag is being reset when i read PA but CA2 remains low and the only way to reset it is to do a full system reset.

Here is my code, perhaps it's my configuration with the 6522?

Code:
VIA:              .SET $9000

;----------System Setup 6522----------------------
;-- Parameters - VOID
;-------------------------------------------------
SYS_INIT6522:
    LDA #@00000000           ; Set all Pins to input
    STA VIA+$02              ; And Set DDR to that on Port B
    LDA #$FF
    STA VIA+$03              ; Set Drive to Output Mode (PA Output)
    LDA #@00001000           ; Negative Active PB & Handshake on CA2
    STA VIA+$0C
    ; Now Set up Timer
    LDA #$FF
    STA VIA+$04              ; Lo Byte Counter FF
    LDA #$FF
    STA VIA+$05              ; Hi Byte Counter FF
    LDA #@01000011           ; Enable Continual Interrupts on T1 & LATCH on PA & PB
    STA VIA+$0B              ; Put it in ACR
    ; Enable Interrupts
    LDA #@11010010           ; Enable Interrupt on Timer1, CB1 AND CA1
    STA VIA+$0E
    RTS


And my Interrupt handler as follows (Keep in mind it also handles the timer and Keyboard)

Code:
;----------Interrupt Request----------------------
;-- Parameters - VOID
;-------------------------------------------------
SYS_IRQ:
    PHA
    LDA #@00000010
    BIT VIA+$0D
    BEQ .checkKeyboard
    M_PRINT_STR STR_DRTC_CALLED ; Print a confirmation that this was called on screen
    LDA VIA+$01 ; Read Data from PORTA of Via - this resets the interrupt
.checkKeyboard
    ; Did a Timer go off or Is Data on PortB
    LDA #@00010000   ; Test for CB1
    BIT VIA+$0D      ; Flag Register of VIA
    BEQ .checkTimer1 ; CB1 didn't interrupt Check Timer
    LDA VIA+$00      ; Read from PortB of the VIA
    STA INPUT_CBUF   ; Store it in input Buffer
.checkTimer1
    LDA #@01000000   ; Check Timer1 Bit
    BIT VIA+$0D      ; Flag Register of VIA
    BEQ .done        ; Not the Timer1 Bit calling Interrupt goto Done
    LDA VIA+$04      ; Read from T1L to clear bit
    INC TIMER_COUNT  ; Increase the Timer
    ; Done checking on the VIA
.done
    PLA
    RTI


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 30, 2022 4:27 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
That's one of the few features I have not used on the VIA; but I'll offer this: According to the data sheet, that line will go false again the next time you write to the port.

To make the code more clear, I would encourage you to name the VIA registers according to the data sheet, rather than referring to VIA+4, etc.. You could have for example, VIA_PB, VIA_PA, VIA_DDRB, VIA_DDRA, VIA_T1CL, VIA_T1CH, etc., so we don't have to look up the numbers.

_________________
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: Thu Jun 30, 2022 4:52 am 
Offline
User avatar

Joined: Sun Nov 07, 2021 4:11 pm
Posts: 101
Location: Toronto, Canada
Writing to the port again does the trick for me. I second Garth’s suggestion of adopting explicit labels for your 6522; if it helps, this is how I do it for my SBC in ca65:

Code:

;-----------------------------------------------------------------------------
; I/O map

.struct VIA1
                  .org $FE10

  PORTB           .byte
  PORTA           .byte

  DDRB            .byte
  DDRA            .byte

  T1C_L           .byte
  T1C_H           .byte

  T1L_L           .byte
  T1L_H           .byte

  T2C_L           .byte
  T2C_H           .byte

  SHR             .byte
  ACR             .byte
  PCR             .byte
  IFR             .byte
  IER             .byte
  ORA_IRA         .byte

.endstruct

.scope VIA_IER_BITS

  SETCLEAR      = %10000000
  TIMER1        = %01000000
  TIMER2        = %00100000
  CB1           = %00010000
  CB2           = %00001000
  SHIFT_REG     = %00000100
  CA1           = %00000010
  CA2           = %00000001

.endscope

.scope VIA_SHIFT_REG_MODES

  MASK          = %00011100

  DISABLED      = %00000000
  SH_IN_T2      = %00000100
  SH_IN_PHI2    = %00001000
  SH_IN_CB1     = %00001100
  SH_OUT_FREE   = %00010000
  SH_OUT_T2     = %00011000
  SH_OUT_CB1    = %00011100

.endscope

.scope VIA_PCR_BITS

  CB2_CTRL_MASK = %11100000
  CB1_CTRL_MASK = %00010000
  CA2_CTRL_MASK = %00001110
  CA1_CTRL_MASK = %00000001

  CB2_NEG_EDGE  = %00000000
  CB2_IND_NEG   = %00100000
  CB2_POS_EDGE  = %01000000
  CB2_IND_POS   = %01100000
  CB2_HAND_OUT  = %10000000
  CB2_PULSE_OUT = %10100000
  CB2_LOW_OUT   = %11000000
  CB2_HIGH_OUT  = %11100000

  CB1_NEG_EDGE  = %00000000
  CB1_POS_EDGE  = %00010000

  CA2_NEG_EDGE  = %00000000
  CA2_IND_NEG   = %00000010
  CA2_POS_EDGE  = %00000100
  CA2_IND_POS   = %00000110
  CA2_HAND_OUT  = 000001000
  CA2_PULSE_OUT = %00001010
  CA2_LOW_OUT   = %00001100
  CA2_HIGH_OUT  = %00001110

  CA1_NEG_EDGE  = %00000000
  CA1_POS_EDGE  = %00000001

.endscope



You can then refer to a register as, for example,
Code:
VIA1::PORTA
. Hope this helps. Cheers!


—Marco


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 30, 2022 4:56 am 
Offline

Joined: Tue Feb 21, 2017 8:32 pm
Posts: 38
Thanks Garth, I will clean up the code in the morning. I’m confused as to why CA2 isn’t transitioning high when CA1 is pulled low in response. But you brought up a point here that I’m wondering about, in my interrupt I do read PA to clear the IR Flag even though the pins are set to output, I know it’s not a write but could that Read be keeping CA2 Low? I will have to try and clear the IR flag manually and see if the transition takes place as expected. If not I do see most people using Pulse mode for handshaking as opposed to Handshake mode.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 30, 2022 5:02 am 
Offline

Joined: Tue Feb 21, 2017 8:32 pm
Posts: 38
Thanks for the suggestion Marco, I’ll implement a similar struct. I’m confused about writing to the port again. I have tried writing to the port but CA2 is stuck low and is not coming back high after my CA1 transition from the peripheral.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 30, 2022 12:07 pm 
Offline
User avatar

Joined: Sun Nov 07, 2021 4:11 pm
Posts: 101
Location: Toronto, Canada
Hi again! I think it might be helpful if you posted the full code that you're trying to puzzle out—ideally stripped of anything superfluous. For example, I don't see here where you write to ORA, so it looks like there's bits missing, and the problem might well be there. This might help us help you find out what's going on.

Unfortunately, I don't have a working board with a 6522 (my SBC is always in some state of flux, it seems!), but I do recall this working for me, and exactly for the same use case, so it's definitely feasible. I don't know if this is useful, but a few suggestions, in order of what I would try:

  • Perhaps consider writing the simplest possible program you can to experiment with this, so that you eliminate all other possible confounding factors. Once you have the smallest possible code, it might be easier to debug and then build it back to the full functionality you need.
  • Use polling instead of interrupts—again, to simplify things. If you can get the handshake to work without interrupts, you can probably figure out the interrupts later :-)
  • If you have one, swap out a different 6522; I don't think it's likely to be the problem, but these things do break, especially if it's the old kind.
  • This post has some code and discussion on automatic handshakes; perhaps it can give you some ideas on how to proceed.

Sorry that these are a bit generic; if you post your full code (minus all the non-handshake part), we might be able to come up with something a bit more specific. Good luck!


—Marco


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 07, 2022 8:30 pm 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
It's a bit late, but I stumbled across this. And you didn't post whether you found a solution.

Maybe° your code will work fine if you set CA2 to manual output mode high (store $0E int PCR) one time before you change the mode to handshake mode.

(°: I think it might be possible that CA2 "returns" to its previous function (the mode it has before you changed the mode to handshake) after a handshake session is complete. If this is true setting manual output mode high once should be sufficient.)

Perhaps it is better to omit PA latching - you use it as an output.

If this one time manual mode high setup wouldn't do the work, it should at least work within your interrupt service routine.


Good luck.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

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