Comment coder pour les E / S bidirectionnelles pour MC6850 ACIA (assembleur 680x)
J'ai besoin d'une liste de codes pour 6802 (ou 6809) pour initialiser et mettre le 6850 ACIA en mode d'E / S série bidirectionnel.
J'ai deux cartes vintage et je dois faire fonctionner et connecter les ports avant de pouvoir faire quoi que ce soit avec eux.
La note d'application Motorola correspondante est absente de ma collection (AN-754), et tout le reste que j'ai le montre.
La plupart des références parlent des registres, mais pas de la manière dont l'interrogation / surveillance ou le flux de contrôle ... code
Réponses
initialisez et réglez le 6850 ACIA en mode d'E / S série bidirectionnel.
Google "6850 ACIA" et regardez la broche. Il y a une ligne "Tx Data" et une ligne "Rx Data" sur la puce. C'est déjà bidirectionnel.
Si vous le souhaitez unidirectionnel, vous ne devez pas faire l'une de ces choses:
Lorsque vous configurez la puce, vous devez mettre un 1 dans le bit 7 du registre de contrôle sur "Receive Interrupt Enable". Vous avez besoin d'une routine IRQ qui vérifie le bit 0 du registre d'état pour s'assurer que c'est ce qui a causé l'IRQ, puis récupère les données du registre de réception de données et les place dans une mémoire tampon.
Je suppose que si vous écrivez un octet dans le registre de transmission de données, l'ACIA commencera à l'envoyer et générera une IRQ une fois terminé. Votre routine IRQ doit vérifier le bit 1 du registre d'état pour s'assurer que c'est ce qui a provoqué l'IRQ, puis placer les nouvelles données d'un tampon dans le registre de données de transmission.
Il semble que vous deviez "Master Reset" la puce en écrivant des 1 dans les bits "Counter Divide" puis en écrivant 00, 10 ou 01 - vous ne savez pas quelle est la valeur correcte pour vos cartes / application.
mais pas comment interroger / surveiller ou contrôler le flux ... code
Sur un processeur de ce type, vous devez essentiellement construire un petit système qui alimente / mange des octets dans / hors de l'ACIA à partir d'un tampon qui est rempli séparément à l'aide d'autres routines. C'est trop spécifique à l'application pour créer du code général.
La plupart des références parlent des registres,
parce que c'est tout ce qu'il y a.
mais pas comment interroger / surveiller ou contrôler le flux ... code
L'interrogation se fait en lisant le registre d'état.
Pour voir si des données ont été reçues, on lit le registre d'état (Offset 0) et vérifie le bit 0:
- S'il est défini, un caractère a été reçu, qui peut maintenant être lu à partir du registre de données (Offset 0).
Pour voir que les données peuvent être envoyées, encore une fois le registre d'état doit être lu, juste cette fois le bit 1 raconte l'histoire:
- S'il est défini, la résistance est vide et un caractère peut être écrit dans (pour être envoyé).
Ou, comme pseudo C comme le code:
while(1)
{
char status = read_status_port;
if(status & 1)
read_byte_from_ACIA();
if(status & 2)
write_byte_to_ACIA();
}
Oui, c'est aussi simple que cela. Bien sûr, je ne peux pas dire comment gérer vos tampons, détecter la fin de la transmission ou similaire. ce n'est que la manipulation en série. Tout le reste dépend de la structure et de l'objectif de votre application ... comme d'habitude.
Et oui, on pourrait entrer dans le fonctionnement en arrière-plan avec des interruptions et de même pour fonctionner en parallèle avec un programme et ainsi de suite, mais je suppose que c'est hors de portée ici.
Voici mon code pour 6809/6850 pour mon ordinateur homebrew . J'espère que ça aide.
Quoi qu'il en soit, la communication est bidirectionnelle "par nature", l'ACIA peut transmettre et recevoir des données au même moment (mais un seul octet à la fois).
Vous pouvez combiner ces deux routines en une seule "transmission-lecture-si-nécessaire" et l'appeler souvent, ou par une interruption.
; serial
ACIA EQU $83fe ;base address ACIAC EQU ACIA ;control register ACIAS EQU ACIA ;status register ACIAD EQU ACIA+1 ;data register INIT: LDA #$15
STA ACIAC
ACIA_TDRE EQU 02h
ACIA_RDRF EQU 01h
; send one byte from A to serial
SEROUT:
PSHS a,b
SEROUTL:
LDB ACIAS
ANDB #ACIA_TDRE
BEQ seroutl
STA ACIAD
PULS a,b
RTS
; Wait for serial char to read
SERIN:
LDA ACIAS
ANDA #ACIA_RDRF
BEQ serin
LDA ACIAD
RTS