Commodore 64 paddles - $DC00

C'est le lieu des discussions diverses et variées, mais toujours en rapport avec le thème général du forum et dans l'esprit de celui-ci. Contient des rubriques électroniques.

Modérateurs : Papy.G, fneck, Carl

Répondre
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Commodore 64 paddles - $DC00

Message par frktaunus »

Bonjour,
J'en appelle ici aux pros du LM qui trainent par ici ;)
j'ai profité d'un peu de temps pour terminer mon programme C64 de test de joystick et paddles en LM.
Les positions du joystick1 sont à lire sur les bits de l'adresse $DC00 (ca c'est ok)

Les bits 6 et 7 servent a switcher entre les paddles A et B pour lire les données 0 à 255 des potars de ces dernières.
Bit 6..7 Switch control port 1 (%01=Paddles A) or 2 (%10=Paddles B)
on lit alors les valeurs potX et potY en $D419 et $D41A
en effet, c'est le SID qui décode l'entrée analogique, et donne le résultat, mais il ne peut décoder que 2 valeurs
donc on doit switcher entre les paddles et lire le résultat de sortie au même endroit.

Donc j'écrase l'adresse $DC00 avec la valeur $40 (01xxxxxx) pour lire les valeur des 2 paddles A
puis j'écrase l'adresse $DC00 avec la valeur $80 (10xxxxxx) pour lire les valeur des 2 paddles B

étrange d'écrire dans une adresse utilisée en lecture, mais bon, ca marche

voici une partie du source

Code : Tout sélectionner

;.paddle A - placer DC00 à 01xxxxxx
  lda #$40
  sta $DC00
  lda $D419 ; position X lue en $D419
  sta $D000 ; ecrite sur position X du sprite 1
  lda $D41A ; position Y lue en $D41A
  sta $D002 ; ecrite sur position X du sprite 2
  
;.paddel B - placer DC00 à 10xxxxxx
  lda #$80
  sta $DC00
  lda $D419 ; position X lue en $D419
  sta $D004 ; ecrite sur position X du sprite 3
  lda $D41A ; position Y lue en $D41A
  sta $D006 ; ecrite sur position X du sprite 4
un programme avec uniquement la 1ère partie paddle A fonctionne bien.
un programme avec uniquement la 2ème partie paddle B fonctionne bien.
le programme complet ,présenté ci-dessus, et c'est le bordel

illustrations:
partie Paddle A seule
partie Paddle A seule
IMG_20220101_183219.jpg (164.59 Kio) Consulté 3005 fois
partie Paddle B seule
partie Paddle B seule
IMG_20220101_183325.jpg (169.5 Kio) Consulté 3005 fois
-
-
A+B
A+B
IMG_20220101_183605.jpg (164.25 Kio) Consulté 3005 fois
-
on dirait que les 4 paddles interfèrent, les sprites bougent sans cesse, rien n'est stable.
si je bouge les paddles, les positions des sprites changent, mais ca clignote de partout.

Remarque:
Paddle A seule: ctrl-restore fonctionne pour revenir au prompt basic
Paddle B seule: ctrl-restore inopérant (?)
A+B, faut insister, mais j'arrive a revenir au prompt

Une idée sur ce problème?
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: Commodore 64 paddles - $DC00

Message par 6502man »

La bonne pratique pour agir que sur 1 ou 2 bit/s est de faire une opération logique pour ne pas affecter les autres bits .
Car la tu force les bits 0 à 5 à zéro ce qui peux créer des problèmes :wink:
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

Je l'ai refait plus propre en ne modifiant que les bits nécessaires.
Pas de changements, tout ce que j'indique dans mon 1er message reste valable

Y aurait-il besoin d'un "délai" entre le set des 2 bits de l'adresse $DC00 et l’obtention du résultat de lecture des potars X/Y par le SID ? :|
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: Commodore 64 paddles - $DC00

Message par Carl »

01.jpg
01.jpg (151.97 Kio) Consulté 2943 fois
Carl
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

Cet exemple de routine appelée par SYS679 calcule la moyenne sur 256 lectures successives des octets liés aux positions X et Y des paddles.
Elle stocke ces moyennes en 250 et 251 pour lecture par Peek du basic.
C'est effectivement utile pour éviter la tremblote de la raquette du casse brique, à cause de l’imprécision de conversion analogique/numérique et des potentiomètres fatigués.

J'ai passé un coup de désoxydant dans les potars des manettes paddles, cela ne vibre quasiment plus. :wink:

Hélas, cette routine ne traite que les signaux du paddle A par défaut.
Mon soucis reste celui de switcher entre les 2(x2) paddles et de faire une lecture bien différenciée.
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: Commodore 64 paddles - $DC00

Message par Carl »

Si c'est pour tester tes paddles, tu peux utiliser ceci :
game-controller-tester-v1.0-2.jpg
game-controller-tester-v1.0-2.jpg (110.27 Kio) Consulté 2921 fois
game-controller-tester-v1.0-1.jpg
game-controller-tester-v1.0-1.jpg (100.73 Kio) Consulté 2921 fois
game-controller-tester-v1.0.zip
(4.71 Kio) Téléchargé 76 fois
Carl
Zebulon
Messages : 2787
Inscription : 02 nov. 2020 14:03

Re: Commodore 64 paddles - $DC00

Message par Zebulon »

Je crois que j'ai trouvé l'explication ici.
In theory, reading the "position" of paddles is as easy as reading byte values from the SID registers at 54297-54298, but to allow for a total of four paddle knobs/potentiometers, the C-64 hardware uses a multiplexer to "switch" between the two control ports. And this complicates matters a bit.

The two most significant bit lines in port A of CIA-1 are used to "tell" the multiplexer which of the joystick ports to connect with. At the same time, these lines are involved in the scanning of the keyboard matrix, and so gets manipulated constantly as the computer scans for keypresses. So reliably reading the paddles implies temporarily disabling the keyboard scan as the reading takes place.

The SID measures the two analog inputs once per 512 machine cycles, or about 1950 times a second, independent of (and thus asynchronous with) the timing of the program the CPU is running, i.e. when the program commands the multiplexer to switch to the other port. So the programmer has to "assume" that the keyboard scan and/or other activities have recently caused the multiplexer to switch ports, set up the multiplexer and disable anything that may interfere with it, then wait for 512 machine cycles to allow the SID to do a full reading, before finally reading the analog input register.
Ta lecture est polluée par le scan du clavier. Plus bas dans l'article il y a un exemple en Basic avec les pokes pour désactiver/activer le scan du clavier.

Ah le Commodore et ses pokes. :D
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

@Carl: Merci je vais regarder ca, mais le but ici c'est de la faire soi-même ;)

@Zebulon
Je désactive bien le clavier en début de programme.
then wait for 512 machine cycles to allow the SID to do a full reading, before finally reading the analog input register
voila, je pense que c'est ça. Merci.
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

Il y a du mieux, mais c'est pas encore ça.

Après le switch adresse de lecture des paddles, j'ai placé une boucle qui ne fait rien (on attend, et j'incrémente un octet écran pour voir que ca tourne)
Le paddle A est désormais toujours bien lu sur les X et Y
Mais pour le paddle B, j'ai visuellement 2 sprites, ceux des positions des paddles B, mais aussi des paddles A.
Donc, le switch n'est pas toujours fait, ou je n'attend pas assez...

Si j'augmente la durée de la boucle au dessus de 2500 fois, le programme plante de suite et le C64 revient au READY.
Etrange...
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: Commodore 64 paddles - $DC00

Message par 6502man »

Est ce que tu procède de cette manière :


Start:
-désactiver le clavier

Loop:
- switcher sur paddle A
- wait
- read analogue value

-switcher sur paddle B
- wait
- read analogue value

- revenir à Loop
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

Exactement!
Je vais partager le programme ici (je suis sur un autre ordi pour le moment)

Il y a sans doute des optimisations/améliorations a apporter, j'ai toujours été solo en LM, je me suis auto-formé au milieu des années 80, avec un bouquin qui présentait la ROM désassemblée du C64, et j'en ai ch... sur le monitor du C128.
La j'y revient très humblement avec C64 studio et Vice -> SD -> C64

Je n'ai pas trouvé comment simuler les paddles sous vice.
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
frktaunus
Messages : 1148
Inscription : 08 mai 2019 11:23
Localisation : LILLE

Re: Commodore 64 paddles - $DC00

Message par frktaunus »

Bonsoir, voila mon code,
et en PJ, le PRG correspondant

Code : Tout sélectionner

!to "joytest.prg",cbm

*=$0801 ;Set BASIC SYS start header
!BASIC 2064

*=$0810 ;Set main code

;* = $1000 ; départ en 4096
;.Start
  jsr $e544 ; effacer l'écran
  ; texte de présentation
  !for COL = 0 To 35
      lda INTL1 + COL 
      sta $400 + 40 + COL  
  !end
  !for COL=0 To 10
      lda INTL2 + COL 
      sta $400 +160 + COL    
  !end
  ; dessiner les joysticks en petscii
  !for COL = 0 TO 4
      lda JOYZ1 + COL 
      sta $4F0 + COL
      sta $4F0 + COL + 6
      lda JOYZ2 + COL 
      sta $518 + COL
      sta $518 + COL + 6
      sta $568 + COL
      sta $568 + COL + 6
            
      lda JOYZ3 + COL
      sta $540 + COL
      sta $540 + COL + 6
      lda JOYZ4 + COL 
      sta $590 + COL          
      sta $590 + COL + 6          
  !end
    
  ; dessiner les rails pour les potars 1 à 4
  !for COL = 0 To 31
    lda #$43
    sta $5E0 + 40 + COL
    sta $5E0 +120 + COL
    sta $5E0 +200 + COL
    sta $5E0 +280 + COL
  !end
  ; désignations liées aux potars
  !for COL= 0 To 2
    lda INTL3 + COL
    sta $5E0 + COL
    sta $5E0 + COL + 80
    sta $5E0 + COL + 160
    sta $5E0 + COL + 240
  !end
  
  lda INTL3+4
  sta $5E0 + 4
  sta $5E0 + 80 + 4
  lda INTL3+5
  sta $5E0 + 160 + 4
  sta $5E0 + 240 + 4
  lda INTL3+6
  sta $5E0 + 5
  sta $5E0 + 160 + 5  
  lda INTL3+7
  sta $5E0 + 80 + 5
  sta $5E0 + 240 + 5

  ; Mise en place des 4 sprites
  lda #$0F   ; Les 4 premiers sprites
  sta $D015 ; sprites On/Off
  ; graphisme des sprites
  !for COL=0 To 62
    lda SPRDATA + COL
    sta $3000 + COL
  !end
  ; sprites pointers
  !for COL=0 to 3
    lda #$C0
    sta $07F8 + COL
  !end
  ; sprites colors
  lda #$01
  sta $D027
  sta $D028
  sta $D029
  sta $D02A
  ; dilatation des sprites en x
  lda #$0F
  sta $D01D
  
  ; positions en X par défaut au départ en 128
  !for COL=0 To 3
    lda #$80
    sta $D000 + (COL*2)
  !end
  ; positions en Y invariable 
  lda #$9A
  sta $D001
  lda #$AA
  sta $D003
  lda #$BA
  sta $D005
  lda #$CA
  sta $D007
  
  ; désactivation du clavier par $E0, activation avec $FF
  lda #$E0
  sta $DC02
    
.JoyStickTest
  ; initialisations registres x et y
  ldx #$51        ; charge le caractère 81D dans X pour symboliser ACTIF
  ldy #$2e        ; charge le caractère 46D dans Y pour symboliser INACTIF

;.JoyStick1
  LDA $dc01       ; récupère l'octet associé au port joystick 1
  and #$10        ; garde le bit 5 dans A (FIRE)
  beq .Fire1Set    ; si A=0, fire est actif, on branche sur affichage de X
  sty $04f3       ; sinon on affiche Y
  jmp .Right1     ; et on va au cas suivant
.Fire1Set
  stx $04f3       ; on affiche X
.Right1           ; RIGHT bit 8
  LDA $dc01       ; récupère l'octet associé au port joystick 1
  and #$08        ; garde le bit 5 dans A (RIGHT)
  beq .Right1Set  ; si A=0, right est actif, on branche sur affichage de X
  sty $0543       ; sinon on affiche Y
  jmp .Left1      ; et on va au cas suivant
.Right1Set
  stx $0543       ; on affiche X
.Left1
  LDA $dc01       ; récupère l'octet associé au port joystick 1
  and #$04        ; garde le bit 3 dans A (LEFT)
  beq .Left1Set   ; si A=0, left est actif, on branche sur affichage de X
  sty $0541       ; sinon on affiche Y
  jmp .Up1        ; et on va au cas suivant
.Left1Set
  stx $0541       ; on affiche X
.Up1
  LDA $dc01       ; récupère l'octet associé au port joystick 1
  and #$01        ; garde le bit 1 dans A (UP)
  beq .Up1Set     ; si A=0, up est actif, on branche sur affichage de X
  sty $051a       ; sinon on affiche Y
  jmp .Dw1        ; et on va au cas suivant
.Up1Set
  stx $051a       ; on affiche X
.Dw1
  LDA $dc01       ; récupère l'octet associé au port joystick 1
  and #$02        ; garde le bit 2 dans A (DW)
  beq .Dw1Set     ; si A=0, up est actif, on branche sur affichage de X
  sty $056a       ; sinon on affiche Y
  jmp .JoyStick2  ; et on va au cas suivant
.Dw1Set
  stx $056a       ; on affiche X
  
.JoyStick2
  LDA $dc00       ; récupère l'octet associé au port joystick 2
  and #$10        ; garde le bit 5 dans A (FIRE)
  beq .Fire2Set    ; si A=0, fire est actif, on branche sur affichage de X
  sty $04f9       ; sinon on affiche Y
  jmp .Right2     ; et on va au cas suivant
.Fire2Set
  stx $04f9       ; on affiche X
.Right2           ; RIGHT bit 8
  LDA $dc00       ; récupère l'octet associé au port joystick 2
  and #$08        ; garde le bit 4 dans A (RIGHT)
  beq .Right2Set  ; si A=0, right est actif, on branche sur affichage de X
  sty $0549       ; sinon on affiche Y
  jmp .Left2      ; et on va au cas suivant
.Right2Set
  stx $0549       ; on affiche X
.Left2
  LDA $dc00       ; récupère l'octet associé au port joystick 2
  and #$04        ; garde le bit 3 dans A (LEFT)
  beq .Left2Set    ; si A=0, left est actif, on branche sur affichage de X
  sty $0547       ; sinon on affiche Y
  jmp .Up2        ; et on va au cas suivant
.Left2Set
  stx $0547       ; on affiche X
.Up2
  LDA $dc00       ; récupère l'octet associé au port joystick 2
  and #$01        ; garde le bit 1 dans A (UP)
  beq .Up2Set     ; si A=0, up est actif, on branche sur affichage de X
  sty $0520       ; sinon on affiche Y
  jmp .Dw2        ; et on va au cas suivant
.Up2Set
  stx $0520       ; on affiche X
.Dw2
  LDA $dc00       ; récupère l'octet associé au port joystick 2
  and #$02        ; garde le bit 1 dans A (DW)
  beq .Dw2Set     ; si A=0, up est actif, on branche sur affichage de X
  sty $0570       ; sinon on affiche Y
  jmp .FinJoy     ; et on va au cas suivant
.Dw2Set
  stx $0570       ; on affiche X  
.FinJoy

;.paddle A - placer $DC00 à 01xxxxxx
  lda $DC00 ; on charge la valeur de DC00
  ora #$40  ; OR  avec 0100 0000 pour avoir x1xx xxxx 
  and #$7F  ; AND avec 0111 1111 pour avoir 01xx xxxx 
  sta $DC00 ; ecrire dans $DC00
  jsr .boucle500 ; il faut attendre 500 cycles avant de lire le SID

  lda #$FF  ; charge FF dans A
  sbc $D419 ; soustraction de la valeur X du paddle A
  sta $D000 ; ecrite sur position X du sprite 1

  lda #$FF  ; charge FF dans A
  sbc $D41A ; soustraction de la valeur Y du paddle A
  sta $D002 ; ecrite sur position X du sprite 2
  
;.paddel B - placer $DC00 à 10xxxxxx
  lda $DC00 ; on charge la valeur de DC00
  ora #$80  ; OR  avec 1000 0000 pour avoir 1xxx xxxx
  and #$BF  ; AND avec 1011 1111 pour avoir 10xx xxxx
  sta $DC00 ; ecrire dans $DC00
  jsr .boucle500 ; il faut attendre 500 cycles avant de lire le SID

  lda #$FF  ; charge FF dans A
  sbc $D419 ; soustraction de la valeur X du paddle B
  sta $D004 ; ecrite sur position X du sprite 3

  lda #$FF  ; charge FF dans A
  sbc $D41A ; soustraction de la valeur Y du paddle B
  sta $D006 ; ecrite sur position X du sprite 4
  
  
jmp .JoyStickTest    ; on reboucle au début de tests des joystick


.boucle500
  !for COL=0 To 1000
    inc $400
    nop
  !end
  rts

;screen char data - texte introduction
!CT SCR
INTL1 !TEXT "joystick / paddle test - f.r.k. 2021"
INTL2 !TEXT "port1 port2"
;screen char data - dessin des joystick en petscii
JOYZ1 !byte $55,$40,$40,$43,$49
JOYZ2 !byte $42,$20,$20,$20,$5d
JOYZ3 !byte $42,$20,$5b,$20,$5d
JOYZ4 !byte $4a,$43,$43,$43,$4b
;screen char data - pour les potar
INTL3 !TEXT "pot abxy"
; data de dessin des sprites
SPRDATA !byte $00,$08,$00,$00,$08,$00,$00,$08,$00,$00,$08,$00,$00,$08,$00,$00,$08,$00,$00,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
Pièces jointes
joytest.zip
(1.44 Kio) Téléchargé 76 fois
Franck
Est ce que l'on peut enregistrer de la musique classique sur une cassette Metal ?
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: Commodore 64 paddles - $DC00

Message par Carl »

La config Paddle sous Vice :
paddle.jpg
paddle.jpg (114.09 Kio) Consulté 2773 fois
mouse grab.jpg
mouse grab.jpg (212.26 Kio) Consulté 2773 fois
tool.jpg
tool.jpg (206.21 Kio) Consulté 2773 fois
tool2.jpg
tool2.jpg (145.48 Kio) Consulté 2773 fois
Carl
lightbeing
Messages : 51
Inscription : 11 déc. 2021 16:05
Localisation : Région parisienne

Re: Commodore 64 paddles - $DC00

Message par lightbeing »

Le programme suivant en LM lit les données des 4 paddles

10 DATA 120,162,2,169,192,141,2,220,41,128,141,0
11 DATA 220,160,208,136,208,253,173,25,212,149,2
12 DATA 173,26,212,149,3,169,64,202,202,16,232,173
13 DATA 1,220,74,74,9,252,133,144,173,0,220,9,243
14 DATA 37,144,73,255,133,144,169,255,141,2,220,96
15 FOR J=49152 TO 49211:READ X:POKE J,X:NEXT

Faire un SYS 49152

Sur port1 : adresse $2 pour les données du paddle X, adresse $3 pour le paddle Y
Sur port2 : adresse $4 pour les données du paddle X, adresse $5 pour le paddle Y

La lecture des données relatives aux paddles sur les registres de la puce SID nécessite une attente de 512 cycles à chaque fois avant de lire à nouveau les données.
Répondre