

1 Introduction
Ce document présente des programmes et des sous-programmes permettant l'exploitation des diverses
fonctionnalités de la maquette 68hc11 (origine : ERP562 et 565), telles que :
Affichage : LCD de caractères ASCII (afficheur de 4 lignes de 20 caractères)
LED 7 segments de 2 digits
LED 3 mm (LED 1, LED 2 et LED3)
Saisie : clavier 16 touches
boutons poussoirs (2)
Gestion d'interruptions temps réel (horloge)
2 Organisation de la maquette
2.1 Implantation de la carte mère
La carte mère comprend le microcontrôleur, un décodeur, un tampon d'adresse ainsi qu'un emplacement pour
une mémoire EEPROM de type 27C256.
En mode bootstrap et en mode normal, les connecteurs de la carte permettent de disposer de tous les ports de
sortie du microcontrôleur; en mode Étendu le connecteur central de la carte permet la connexion d'une carte
comprenant une extension mémoire et un module d'E/S parallèles (2*8 bits); le mode de fonctionnement du
microcontrôleur est déterminé par la position des cavaliers ModA et ModB au moment du Reset :
Mode BootStrap : les 2 cavaliers doivent être en placeL'implantation de la carte avec les différents brochages est donnée par la figure suivante :
Mode Normal : seul le cavalier ModB doit être en place
Mode Étendu : aucun des cavaliers ne doit être installé
Le schéma d'implantation de la carte mère est disponible en 2 versions :
Le schéma électrique de la carte mère est disponible en 2 versions :
2.3.1 Ressources internes
2.3.2 Mode Étendu
En mode Étendu (uniquement pour 68hc11A1), la table de l'espace adressable définie par la carte est donnée
par le tableau ci-après :
2.4.1 Mode bootstrap
En mode Bootstrap, le vecteur d'initialisation (Reset) pointe vers la ROM boot (adresse $BF40), ce qui lance
une routine (Bootloader) de téléchargement d'un programme de 256 Octets (exactement !) en RAM; l'exécution de ce
programme démarre après le chargement du 256ème octet, il peut s'agir, par exemple, du "Talker" utilisé par le
moniteur (PCBug11).
Il est ensuite possible d'exécuter un programme à partir de l'EEPROM (adresse $B600 ou $F800); la gestion
des vecteurs d'interruption est alors effectuée par des appels de sous-programmes placés en haut de la RAM (
adresses $C4 à $FF). À titre d'exemple, le gestion d'une interruption RTI se fait en écrivant, à partir de l'adresse $EB
le mnémonique du saut vers le sous-programme sur 3 Octets :
Gestion RTI : $EB : $7E (Code JMP) $EC-$EE : @ SP (2 octets).
Pour exécuter un programme en mode Bootstrap sous le contrôle de PCBug11, il faut placer les variables de
programme et la pile dans plage d'adresses $B0-$C3, soit 20 octets; il est également possible d'exploiter l'espace des
interruptions qui ne sont pas validées (plage $C4-$FF). Le tableau suivant donne la carte de la mémoire RAM en
mode Bootstrap :
Le schéma électrique de la carte clavier-affichage est disponible en 2 versions :
LCD_Time.ASC : microcontrôleur 68hc811E2 en mode Normal
3.1.1.1 Mode Bootstrap
... n'oubliez pas de consulter les annexes
2.2 Schéma électrique de la carte mère
complète : image de 2300*2100 pixels (116 ko)
écran : image de 800*600 pixels (21 ko)
2.3 espace d'adressage
Le microcontrôleur est capable d'adresser 64 kOctets (adresse sur 16 bits) en mémoire, il peut s'agir de RAM,
de ROM (masquée, EPROM ou EEPROM) ou de registres de configuration; les ressources peuvent être internes ou
externes, en cas de conflit (plusieurs entités à la même adresse), les ressources internes sont prioritaires. En mode
Bootstrap, et en mode Normal, il n'est possible d'exploiter que les ressources internes.
Type 68hc11A1 68hc811E2 Taille Registres $1000-$103F 64 registres RAM $0000-$00FF 256 Octets ROM Boot $BF40-$BFFF 192 Octets ROM Interne $E000-$FFFF - 8kOctets/- EEPROM $B600-$B7FF $F800-$FFFF 512 Octets/ 2kOctets
Adresse Hexa A15 .................A0 CONTENU $0000-$00FF %0000 0000 0000 0000 256 OCTETS RAM $0100-$0FFF %0000 0001 0000 0000 $1000-$103F %0001 0000 0000 0000 64 REGISTRES $1040-$1FFF %0001 0000 0100 0000 $2000-$3FFF %0010 0000 0000 0000 RAM Externe: 8ko. $4000-$B5FF %0100 0000 0000 0000 $B600-$B7FF %1011 0000 0000 0000 512 OCTETS EEPROM $B800-$BFFF %1011 1000 0000 0000 $C000-$FFBF %1100 0000 0000 0000 EPROM PROGRAMME $FFC0 %1111 1111 1100 0000 VECTEURS IT & RESET 2.4 Vecteurs d'interruption
Les adresses et la gestion des vecteurs d'interruption dépendent du type de processeur et du mode de
fonctionnement :
Adresses Taille Type Source d'interruption Masque
(Octets) Global Local $0000-$00AF 175 Prog. (PCBug11) - - - $00B0-$00C3 20 Dispo. - - - $00C4-$00C6 3 Int. (PCBug11) SCI : Liaison série asynchrone I - $00C7-$00C9 3 Int. SPI : Liaison série synchrone I SPIE $00CA-$00CC 3 Int. Entrée du compteur I PAII $00CD-$00CF 3 Int. Débordement du compteur I PAOVI $00D0-$00D2 3 Int. Débordement du timer I TOI $00D3-$00D5 3 Int. OC5 : Comparateur 5 I OC5I $00D6-$00D8 3 Int. OC4 : Comparateur 4 I OC4I $00D9-$00DB 3 Int. OC3 : Comparateur 3 I OC3I $00DC-$00DE 3 Int. OC2 : Comparateur 2 I OC2I $00DF-$00E1 3 Int. OC1 : Comparateur 1 I OC1I $00E2-$00E4 3 Int. IC3 : Entrée de capture 3 I IC3I $00E5-$00E7 3 Int. IC2 : Entrée de capture 2 I IC2I $00E8-$00EA 3 Int. IC1 : Entrée de capture 1 I IC1I $00EB-$00ED 3 Int. RTI : Interruption temps réel I RTII $00EE-$00F0 3 Int. IRQ ou STRA I non/STAII $00F1-$00F3 3 Int.(PCBug11) XIRQ X - $00F4-$00F6 3 Int.(PCBug11) SWI : interruption logicielle - - $00F7-$00F9 3 Int. Code illégal - - $00FA-$00FC 3 Int. COP : Chien de garde - NOCOP $00FD-$00FF 3 Int. Défaut d'horloge -
Adresses Source d'interruption Masque Global Local $FFD6-$FFD7 SCI : Liaison série asynchrone I - $FFD8-$FFD9 SPI : Liaison série synchrone I SPIE $FFDA-$FFDB Entrée du compteur I PAII $FFDC-$FFDD Débordement du compteur I PAOVI $FFDE-$FFDF Débordement du timer I TOI $FFE0-$FFE1 OC5 : Comparateur 5 I OC5I $FFE2-$FFE3 OC4 : Comparateur 4 I OC4I $FFE4-$FFE5 OC3 : Comparateur 3 I OC3I $FFE6-$FFE7 OC2 : Comparateur 2 I OC2I $FFE8-$FFE9 OC1 : Comparateur 1 I OC1I $FFEA-$FFEB IC3 : Entrée de capture 3 I IC3I $FFEC-$FFED IC2 : Entrée de capture 2 I IC2I $FFEE-$FFEF IC1 : Entrée de capture 1 I IC1I $FFF0-$FFF1 RTI : Interruption temps réel I RTII $FFF2-$FFF3 IRQ ou STRA I non/STAII $FFF4-$FFF5 XIRQ X - $FFF6-$FFF7 SWI : interruption logicielle - - $FFF8-$FFF9 Code illegal - - $FFFA-$FFFB COP : Chien de garde - NOCOP $FFFC-$FFFD Défaut d'horloge - CME $FFFE-$FFFF RESET - - 2.5 Schéma électrique de la carte Clavier-Affichage
Cette carte sert d'interface homme-machine avec la carte mère, elle dispose d'un afficheur LCD de 4
lignes de 20 caractères, de 2 digits LED et de 3 LED 3 mm; la saisie peut se faire par un clavier de 16 touches et par
2 boutons poussoirs.
complète : image de 2500*2000 pixels (113 ko)
écran : image de 800*600 pixels (20 ko)
2.6 Transfert SPI
La particularité des maquettes est d'utiliser l'interface série synchrone (SPI) pour dialoguer entre la carte
processeur et la carte clavier-affichage; les transferts sont organisés sous forme de 2 envois vers la carte Clavier-
afficheur et d'une lecture.
*
* Premier mot envoyé : Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0
* | R | B | D | U | L | NC | RS | E |
* Relais ____| | | | | | |
* Buzzer _________| | | | | |
* | | | | |
* Afficheur 7 Seg. Dizaines ____________| | | | |
* Unités ___________________| | | |
* | | |
* LED ___________________________| | |
* | |
* Afficheur LCD Register Select __________________________| |
* Enable _______________________________________|
*
* Le deuxième mot envoyé correspond aux données
*
* Afficheur 7 Seg. : Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0
* | d | e | c | dp | b | a | f | g |
*
* Afficheur LCD : Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0
* | q7 | q6 | q5 | q4 | q3 | q2 | q1 | q0 |
*
*
* Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0
* LED : | | k3 | | | k2 | | | k1 |
* Clavier : | | | | | r4 | r3 | r2 | r1 |
* Interrupteurs : | | | | S | | | | |
*
*
* Commandes Afficheur LCD RS (Register Select) : 0 -> Instr. Reg.
* 1 -> Data Reg.
Le protocole SPI est indiqué par la figure suivante (N.B. : le signal SS doit être géré par
logiciel) :

2.7 Registres internes du microcontrôleur
La liste de la plupart des registres de contrôle internes avec leur adresse (relativement à
$1000) est donnée ci-après :
porta equ 0 ; Port A (3 in, 5 out)
pioc equ 2 ; Parallel I/O C Control Reg.
portc equ 3 ; Port C
portb equ 4 ; Port B (output only)
portcl equ 5 ; Port C Control
ddrc equ 7 ; Data Direction Reg Port C
portd equ 8 ; Port D
ddrd equ 9 ; Data Direction Reg Port D
porte equ $A ; Port E
cforc equ $B ; Compare Force Register
oc1m equ $C ; OC1 Action Mask Register
oc1d equ $D ; OC1 Action Data Register
tcnt equ $E ; (16 bits) : Timer Counter Register
tic1 equ $10 ; (16 bits) : Input Capture 1 Register
tic2 equ $12 ; (16 bits) : Input Capture 2 Register
tic3 equ $14 ; (16 bits) : Input Capture 3 Register
toc1 equ $16 ; (16 bits) : Output Compare 1 register
toc2 equ $18 ; (16 bits) : Output Compare 2 register
toc3 equ $1A ; (16 bits) : Output Compare 3 register
toc4 equ $1C ; (16 bits) : Output Compare 4 register
toc5 equ $1E ; (16 bits) : Output Compare 5 register
tctl1 equ $20 ; Timer Control Register 1
tctl2 equ $21 ; Timer Control Register 2
tmsk1 equ $22 ; Timer Mask Register 1
tflg1 equ $23 ; Timer Flag Register 1
tmsk2 equ $24 ; Timer Mask Register 2
tflg2 equ $25 ; Timer Flag Register 2
pactl equ $26 ; Pulse Accumulator Control Reg.
spcr equ $28 ; SPI Control Register
spsr equ $29 ; SPI Status Register
spdr equ $2A ; SPI Data Register
baud equ $2B ; SCI Baud Rate Control
sccr1 equ $2C ; SCI Control Register 1
sccr2 equ $2D ; SCI Control Register 2
scsr equ $2E ; SCI Status Register
scdr equ $2F ; SCI Data Register
adctl equ $30 ; A/D Control/Status Register
adr1 equ $31 ; A/D Result Register 1
adr2 equ $32 ; A/D Result Register 2
adr3 equ $33 ; A/D Result Register 3
adr4 equ $34 ; A/D Result Register 4
bprot equ $35 ; Block Protection
option equ $39 ; System Configuration Options
coprst equ $3A ; Arm/Reset COP Timer circuitry
pprog equ $3B ; EEPROM Programming Register
hprio equ $3C ; Highest Priority Int. Reg.
config equ $3f ; COP, ROM & EEPROM enables
2.8 Constantes de la carte
************************************************************
* Constantes du programme *
************************************************************
base_reg equ $1000
** mots de commande (premier mot envoyé sur SPI)
RIEN equ $FC ; aucun affichage
LCD_on equ $FF ; affichage LCD
LCD_config equ $FD ; configuration de l'afficheur LCD
LED_on equ $F6 ; sélection des LED
unites equ $DE ; sélection de l'afficheur des unités
dizaines equ $EE ; sélection de l'afficheur des dizaines
buzzer equ $BE ; sélection du buzzer
relais equ $7E ; sélection du relais
switches equ $10 ; interrupteurs
** mots de donnée (deuxième mot envoyé sur SPI)
LED_k1 equ $1 ; cathode de la LED 1
LED_k2 equ $8 ; cathode de la LED 2
LED_k3 equ $40 ; cathode de la LED 3
3 Programmes assembleur
Les programmes et sous-programmes présentés ci-dessous ont pour but de fournir des utilitaires de
développement pour les maquettes 68hc11; ces programmes sont présentés comme des modules élémentaires, les
variables exploitées sont rapellées en début de listing (en commentaire); sauf mention contraire, l'utilisation des sous-
programmes n'entraine de modification du contexte (accus, registres, ...). En plus des procédures d'initialisation, sont
présentés les modules suivants :
Aff_msg(Y) : affiche la chaîne de caractères pointée par Y sur l'afficheur LCD)
variable modifiée : data_in
Aff_7seg(digit1,digit10) : affiche digit1 et digit10 sur les afficheurs 7 segments LED
variable modifiée : data_in
Aff_LED(A) : allume la diode LED définie par l'accumulateur A (LED_k#)
Lect_clavier() : effectue une lecture des touches du clavier et des interrupteurs
Valeur retournée : retour : touche : valeur du clavier (4 bits) ou $FF si rien
inter : état des interrupteurs (0 : S1, 1 : S2 et $FF : rien)
En annexe de ce document, sont fournis 2 programmes qui ont servi à bâtir ces modules utilitaires, ils ont
exactement la même fonctionnalité (affichage d'un message et de l'heure) mais ils sont utilisés sur 2 processeurs
différents :
LCD_A1.asc : microcontrôleur 68hc11A1 en mode Bootstrap (PCBug11) et en mode Normal
3.1 Initialisation
3.1.1 Index, Pile et Vecteurs
************************************************************
* variables du programme *
************************************************************
ORG $00B0
variable1 RMB 1
...
************************************************************
* constantes du programme *
************************************************************
JUMPEXT equ $7E ; mnémonique de l'instruction JMP
JRTI equ $00EB ; adresse du vecteur RTI
...
ORG $F800 ; cas d'un 68hc811e2 ($B600 pour 68hc11a1)
Debut SEI ; set interrupt mask
LDAA #JUMPEXT ; mnémonique de l'instruction JMP
LDX #Rti ; adresse du sous-programme d'IT (ici : RTI)
STAA JRTI ; ecriture de JMP Rti à partir de l'adresse $EB
STX JRTI+1 ;
.... autres définitions de vecteurs
LDX #base_reg ; X <--- $1000 : base des registres
LDS #$E7 ; initialisation de la pile à $E7
.... autres initialisation
CLI
.... départ du programme
3.1.1.2 Mode Normal
68hc11A1 : même procédure qu'en mode Boostrap mais les variables peuvent être placées à partir de $0.
68hc811E2 : même procédure qu'en mode Étendu
3.1.1.3 Mode Étendu
************************************************************
* variables du programme *
************************************************************
ORG $0000 ; cas de la RAM interne ($2000 pour la RAM externe)
variable1 RMB 1
...
ORG $FFF0 ; vecteur RTI (exemple)
FDB Rti ; adresse du sous-programme d'IT (ici : RTI)
ORG $FFFE ; vecteur RESET
FDB Debut ; début du programme
ORG $F800 ; cas d'un 68hc811e2
;($B600 pour 68hc11a1 ou $C000 pour EPROM externe)
Debut SEI ; set interrupt mask
.... autres initialisation
CLI
.... départ du programme
3.1.2 SPI
************************************************************
* initialisation SPI *
************************************************************
Init_SPI BSET ddrd,x,#$38 ; SS, SCK, MOSI en sortie
LDAA #$51 ; Enable SPI avec SCK=125kHz, wired_or mode
STAA spcr,x
LDAA #$3F ; on met les bits du port D à 1
STAA portd,x
3.1.3 Afficheur LCD
************************************************************
* initialisation LCD *
************************************************************
*Commande_LCD RMB 1 ; mot de commande du LCD (0: commande; 2 : affichage)
*LCD_config equ $FD ; configuration de l'afficheur LCD
Init_LCD LDAA #LCD_config ; mode config LCD
STAA Commande_LCD
LDAA #$1 ; clear Display
JSR Aff_LCD
** l'afficheur a besoin d'une tempo
Tempo LDY #$1000 ; IY <- durée
T1 DEY ; IY <- IY-1
BNE T1
LDAA #$E ; display =on
JSR Aff_LCD
LDAA #$3C ; N =2 lignes; F = 1
JSR Aff_LCD
3.2 Affichage
3.2.1 Procédure d'appel d'affichage LCD
LDY #introduction
JSR Aff_msg
...
introduction FCC ' On affiche ce texte\'
3.2.2 Préambule d'affichage LCD
******************************************************************
* SP * préparation de l'affichage LCD *
******************************************************************
*Commande_LCD RMB 1 ; mot de commande du LCD (0: commande; 2 : affichage)
Aff_LCD PSHB
LDAB Commande_LCD
JSR OUTSPI ; on envoie la commande (E=1)
ANDB #$FE ; Disable
JSR OUTSPI ; on renvoie la commande (E=0)
PULB
RTS
3.2.3 Affichage d'une chaîne de caractères sur LCD
*******************************************************************
* SP * envoi d'une chaine de caractères pointée par y finie par \ *
*******************************************************************
Aff_msg PSHA
PSHY
LDAA #LCD_config ; mode config LCD
STAA Commande_LCD
LDAA #$80 ; DD Ram =$00
JSR Aff_LCD
LDAA #LCD_on ; mode Affichage LCD
STAA Commande_LCD
Envmot LDAA 0,y
CMPA #'\'
BEQ Envmot_fin ; si \ alors retour
JSR Aff_LCD ; si non envoi du caractère (0,y)
INY ; IY <- IY + 1
BRA Envmot ; on boucle
Envmot_fin PULY
PULA
RTS
3.2.4 exemple : affichage de l'heure sur l'afficheur LCD
*************************************************************************
* SP * Affichage de l'heure sur l'afficheur LCD *
*************************************************************************
*seconde RMB 1 ; nbre de secondes de 0 à 256 pour ajustement
*secondes RMB 1 ; secondes de 0 à 59
*minutes RMB 1 ; minutes de 0 à 59
*heures RMB 1 ; heures de 0 à 23
Affhm LDAA #LCD_config ; mode config LCD
STAA Commande_LCD
LDAA #$C7 ; DD Ram =$47
JSR Aff_LCD
LDAA #LCD_on ; RS = 1
STAA Commande_LCD
LDAA heures
JSR Aff_ascii
LDAA #':'
JSR Aff_LCD
LDAA minutes
JSR Aff_ascii
LDAA #':'
JSR Aff_LCD
LDAA secondes
JSR Aff_ascii
RTS
** envoi en DECIMAL ASCII du nombre contenu dans A
Aff_ascii PSHB ; sauvegarde de B
JSR Div_10 ; division par 10 de A
STAA digit10
STAB digit1
ADDA #$30 ; A <- A + $30
JSR Aff_LCD ; envoi du digit Quotient (dizaines)
TBA ; A <- B
ADDA #$30 ; B <- B + $30
JSR Aff_LCD ; envoi du digit Reste (unités)
PULB pulb ; restauration de B
RTS
** DIVISION PAR 10 ----------------------------
** donnee dans A -> A/10 ds A et reste ds B
Div_10 TAB ; B <-- A
CLRA ; A <- 0 : variable dans AccD
LDX #10 ; ix <- 10
IDIV ; Q:IX ; R:AccD <- AccD/IX
PSHB ; push B : Pile <- MSB du reste
XGDX ; Accd <-> IX
TBA ; A <-- B
PULB ; pull B : B <- MSB du reste
LDX #base_reg ; réinitialisation de IX ($1000)
RTS ; return
3.2.5 Affichage de 2 digits LED 7 segments
*************************************************************************
* SP * Affichage sur les afficheurs 7 segments LED *
* digit1 correspond aux unités *
* digit10 correspond aux dizaines *
*************************************************************************
*digit1 RMB 1 ; digit des unités de l'afficheur LED
*digit10 RMB 1 ; digit des dizaines de l'afficheur LED
Aff_7seg PSHY
PSHB
PSHA
LDY #Tab_7seg ; on pointe sur la table de conversion
LDAA c244 ; chargement du compteur d'horloge c244
ASRA ; on propage le LSB dans C
BCC Aff2 ; c244 est pair (C=0), on affiche les unités
LDAB #dizaines ; adresse du digit à afficher
PSHB
LDAB digit10 ; chargement du digit à afficher
BRA Fin_7seg
Aff2 LDAB #unites ; adresse du digit à afficher
PSHB
LDAB digit1 ; chargement du digit à afficher
Fin_7seg ABY ; Y <-- Y + B ( B :offset dans la table)
LDAA 0,y ; pointage sur la table
PULB ; on récupère l'adresse du digit
JSR OUTSPI ; envoi du digit
PULA
PULB
PULY
RTS
* segment : dec.bafg
Tab_7seg FCB #%11101110 ; chiffre 0
FCB #%00101000 ; chiffre 1
FCB #%11001101 ; chiffre 2
FCB #%10101101 ; chiffre 3
FCB #%00101011 ; chiffre 4
FCB #%10100111 ; chiffre 5
FCB #%11100111 ; chiffre 6
FCB #%00101100 ; chiffre 7
FCB #%11101111 ; chiffre 8
FCB #%10101111 ; chiffre 9
FCB #%01101111 ; chiffre A
FCB #%11100011 ; chiffre b
FCB #%11000001 ; chiffre c
FCB #%11101001 ; chiffre d
FCB #%11000111 ; chiffre E
FCB #%01100111 ; chiffre F
3.2.6 Affichage sur les 3 diodes LED
*************************************************************************
* SP * Affichage diodes LED *
* Le numéro de la LED (LED_k#) se trouve dans l'accumulateur A *
*************************************************************************
Aff_LED PSHB
LDAB #LED_on ; mot de commande pour les diodes LED
JSR OUTSPI
PULB
RTS
3.3 Transfert SPI
************************************************************************
* SP * Envoi de 2 octets par SPI et réception d'un octet *
* - Le mot de commande est dans l'accumulateur B *
* - Les données en émission sont dans l'accumulateur A *
* - la donnée en réception est dans data_in *
************************************************************************
*data_in RMB 1 ; lecture sur SPI
OUTSPI PSHA ; on empile la donnée
PSHB ; on empile le mot de commande
PSHY
BCLR portd,x,#$20 ; met SS à 0 latche entrée et sortie registres
STAB spdr,x ; envoi du mot de commande
LDY #08 ; 8 bits à faire tourner
RBBMIR ROLA ; les bits sortent à gauche par la retenue
RORB ; et rentrent à droite par la carry
DEY
BNE RBBMIR
ATE20 BRCLR spsr,x,#$80 ATE20 ; attend fin transmission prec.
LDAA spdr,x ; on récupère la donnée sur le SPI
STAA data_in ; enregistre
STAB spdr,x ; on envoie la donnée sur le SPI
ATEF2O BRCLR spsr,x,#$80 ATEF2O ; attend fin transmission pour reset SS
BSET portd,x,#$20 ; met SS à 1 (delatche sorties registres)
PULY
PULB ; on restaure le mot de commande dans B
PULA ; on restaure la donnée dans A
RTS
3.4 Saisie du clavier
******************************************************************************
* SP * Lecture du clavier et des interrupteurs *
* touche : lecture du clavier (4 bits ou $FF si rien) *
* inter : état des interrupteurs (0 : S1, 1 : S2 et $FF : rien) *
******************************************************************************
*touche RMB 1 ; touche frappée sur le clavier (4 bits ou $FF si rien)
*inter RMB 1 ; interrupteurs (0 : S1, 1 : S2 et $FF : rien)
Lect_clavier PSHA
PSHB
PSHY
Init_lect LDAA #$FF
STAA inter
STAA touche
LDAA #1 ; on pointe sur la 1ère rangée
LDAB #RIEN ; mot de commande nul
BRA Lect_2
Lect_1 ASLA ; rangée suivante
BEQ Fin_lect ; fin du balayage des rangées
Lect_2 JSR OUTSPI ; on stimule
JSR OUTSPI ; on réceptionne la donnée (4 bits LSB)
BRSET data_in,#$0F,Lect_1 ; réponse vierge ?, si oui on boucle
COM data_in ; complémentation de la donnée
CMPA #switches ; adressage des interrupteurs ?
BEQ Lect_int ; il 'agit d'un interrupteur !
JSR Lin_bin ; conversion en binaire (résultat dans B)
PSHB ; sauvegarde du résultat "rangée"
LDAA data_in ; réponse "colonne"
JSR Lin_bin ; conversion en binaire (résultat dans B)
ASLB
ASLB
PULA ; récupération du résultat "rangée"
ABA ; mise en forme de la réponse clavier
TAB
LDY #Tab_clavier
ABY
LDAA 0,Y
STAA touche
Fin_lect PULY
PULB
PULA
RTS
Lect_int LDAA data_in
RORA
STAA inter
BRA Fin_lect
Lin_bin LDAB #0 ; compteur à zéro
Lin_1 RORA ; on décale
BCS Fin_lin ; fin si on a propagé un 1 dans C
CMPB #3 ; fin des 4 bits ?
BEQ Fin_lin ; si oui alors fin
INCB ; incrémentation du compteur
BRA Lin_1 ; on boucle
Fin_lin RTS
* on lit : 147A2580369BFEDC
Tab_clavier FCB #$1
FCB #$4
FCB #$7
FCB #$A
FCB #$2
FCB #$5
FCB #$8
FCB #$0
FCB #$3
FCB #$6
FCB #$9
FCB #$B
FCB #$F
FCB #$E
FCB #$D
FCB #$C
3.5 Gestion des interruptions temps réel (RTI)
3.5.1 Initialisation et préparation RTI
************************************************************
* Début du programme *
************************************************************
Debut SEI ; set interrupt mask
LDX #base_reg ; X <--- $1000
LDS #$FF ; initialisation de la pile à FF
BSET pactl,x,#0 ; rti rate : 4,10 ms
BSET tmsk2,x,#$40 ; rti Interrupt Enable
...
***************************************************************
* Départ du programme *
***************************************************************
LDY #introduction
JSR Aff_msg
...
B1 SEI
...
JSR Lect_clavier
JSR Aff_7seg
CLI ; Clear interrupt Mask
WAI ; Attente d'une interruption
JMP B1
3.5.2 Gestion de l'interruption RTI : exemple de calcul de l'heure
******************************************************************
* INT * Gestion de l'interruption périodique *
* RTI * calcul de l'heure *
******************************************************************
*c244 RMB 1 ; compte 244 interuptions RTI avant d'obtenir 1s.
*bis RMB 1 ; indique à ff que l'on a ajouté le reste
*seconde RMB 1 ; nbre de secondes de 0 à 256 pour ajustement
*secondes RMB 1 ; secondes de 0 à 59
*minutes RMB 1 ; minutes de 0 à 59
*heures RMB 1 ; heures de 0 à 23
** toutes les 256 s, on charge c244 avec le reste (16) pour ajuster l'horloge
Rti DEC c244
BEQ Rti_0
JMP Fin_rti
Rti_0 BSET c244,#244 ; recharge le compteur
BRSET bis,#$ff,Rti_1 ; bis indique que l'on a déjà re-
* chargé c244 avec le reste
INC seconde ; inc sauf si bis = $ff
* chaque fois que seconde passe à 0
BNE Rti_2 ; on charge bis à ff et c244 à 16 (reste)
* on ne compte pas cette "seconde"
Rti_01 LDAA #16 ; on charge le reste
STAA c244
BSET bis,#$ff
JMP Fin_rti
Rti_1 CLR bis
Rti_2 JSR Affhm
LDAA #60
INC secondes ; secondes de 0 à 59
CMPA secondes
BNE Fin_rti
CLR secondes
INC minutes
LDAA #60
CMPA minutes
BNE Fin_rti ; minutes
CLR minutes
INC heures
LDAA heures
CMPA #24
BNE Fin_rti ; heures
CLR heures
Fin_rti BCLR tflg2,x,#$BF ; annule flag RTI
RTI