;**** quartz 14.7 mhz > cycle à 272 ns ; avec une roue de 26 pouces : ; 5 km/h > 1 tour en 1,4 seconde ;70 km/h > 1 tour en 106 millième de seconde #include ".\P16F876.inc" ;***** Micro utilisé / Bits de config PROCESSOR 16F876 __Idlocs H'1204' ;Identification [MMJJ] (date de la sauvegarde de la version) __Config b'0011111100110010' ;CP1-CP0-DEBUG-NU-WRT-CPD-LVP-BODEN-CP1-CP0-PWRTE-WDTE-F0SC1-F0SC0 ;************** ;* constantes * ;************** Voption equ b'00000111' ;RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0 ;***** portA ;non utilisé ;***** portB VPB equ b'00000000' TPB equ b'00000001' ;RBO utilisé comme capteur de tour avec gestion d'interruption INT ;RB1-7 sont les commandes des LEDs 0=éteinte 1=allumée ;***** portC VPC equ b'00000000' TPC equ b'10111111' ;RC7 est l'éméteur TXD de l'interface série ;RC6 est le récepteur RXD de l'interface série ;*********************** ;* alocation de la RAM * ;*********************** sutats equ h'20' ae equ 0 ;RS232 détection daractère "escape" ac equ 1 ;RS232 détection de la séquence ANSI se equ 2 ;demande de sauvegarde en EEPROM ov equ 3 ;débordement du timer cycle cd equ 4 ;débordement du temps maximal de cycle syn equ 5 ;top de synchronisation du défilement du message temp equ h'21' temp0 equ h'22' temp1 equ h'23' temp2 equ h'24' temp3 equ h'25' w_t equ h'26' ;sauvegarde du registre W lors d'une IT s_t equ h'27' ;"" STATUS "" p_t equ h'28' ;"" PCLATH "" rxbuf equ h'29' ;buffer de réception interface série RS232 atH equ h'2a' ;base de temps du segment bit 18-16 ath equ h'2b' ;"""" 15-8 atl equ h'2c' ;"""" 7-0 peaf equ h'2e' ;pointeur du caractère à afficher dans l'EEPROM offset equ h'2f' ;offset pour le déilement du message par increment de peaf dly equ h'30' ;nombre de tour pour commencer le défilement de l'affichage par offset synH equ h'31' ;pour le calcul intermédiaire de la comparaison au timer1 synL equ h'32' ; ;adresses h'70' à h'7f' communes à toutes les pages de ram debugres equ h'70' ;reserver pour le debug ICD2 PTRH equ h'71' ;pointeur d'adresse de lecture en FLASH PTRL equ h'72' PTREH equ h'73' ;pointeur d'adresse de lecture en EEprom PTREL equ h'74' pe equ h'75' ;pointeur du curseur RS232 pour édition EEPROM ped equ h'76' ;valeur à sauvegarder dans l'EEPROM pea equ h'77' ;adresse de la valeur à sauvegarder dans l'EEPROM DATAL equ h'78' ;valeur basse lue en mémoire flash PTRAH equ h'79' ;pointeur d'adresse de lecture en FLASH pour l'affichage PTRAL equ h'7a' ;"" segh equ h'7b' ;segment lue depuis la flash segl equ h'7c' ;"" ;******************************* ;* vecteurs du microcontrôleur * ;******************************* PREMIERE ORG .0 GOTO INIT ;vecteur après mise sous tension ,watch dog ou reset INTER ORG .4 ;**************************** ;* gestion des interuptions * ;**************************** ;**** durée max de traitement ;TMR1IF 26 x Fosc/4 7 µs ;INTF 71 x Fosc/4 19 µs dépendant de l'état de l'ILS et de l'attente de synchro ;RCIF 20 x ASCII ~21ms à 9600 bauds ;***** sauvegarde des registres système MOVWF w_t ;Copy W to TEMP register SWAPF STATUS,W ;Swap status to be saved into W CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0 MOVWF s_t MOVF PCLATH,w MOVWF p_t CLRF PCLATH ;***** détermine la nature de l'interuption (timer1, ILS, reception d'un caractère sur l'interface série) btfsc INTCON,INTF goto ILS ;action sur l'ILS btfsc PIR1,TMR1IF incf atH,f ;incrementation de atH due au débordement du timer 1 btfsc atH,3 ;test si on dépasse 1.12 s soit en dessous de 6.6 km/h bsf sutats,cd bcf PIR1,TMR1IF btfsc PIR1,RCIF goto RS0 ;réception d'un caratère sur l'interface série goto FINTER ;fin de la gestion de l'IT "TMR1IF" ;***** reception sur l'interface séire et filtrage du caractère reçu RS0 movf RCREG,w movwf rxbuf btfsc sutats,ae goto RS1 ;séquence ANSI en cours de réception 2ème caractère btfsc sutats,ac goto RS2 ;séquence ANSI en cours de réception aiguillage de la fonction sublw h'1B' ;test si c'est le code ASCII ESC du début d'une séquence ANSI btfsc STATUS,Z bsf sutats,ae movlw h'20' ;test le code ASCII le + petit recevable subwf rxbuf,w btfss STATUS,C goto FINTER btfsc rxbuf,7 ;test le code ASCII le + grand recevable goto FINTER ;***** routine de gestion des caractères reçus bsf STATUS,RP0 ;bank 1 btfss TXSTA,TRMT ;attend la fin de la transmission en cours goto $-1 bcf STATUS,RP0 ;bank 0 movf rxbuf,w movwf TXREG ;envoie le caractère sur l'interface pour en faire l'écho movwf ped ;positionne la valeur à sauvegarder dans l'EEPROM movf pe,w movwf pea ;et son adresse de destination bsf sutats,se ;demande de sauvegarde en EEProm movlw low gauche ;déplacement du curseur ANSI et gestion des sauts de lignes/colonnes movwf PTRL movlw high gauche movwf PTRH call mes goto RSdroite ;***** deuxième caractère de la sequence ANSI RS1 bcf sutats,ae sublw h'5b' btfsc STATUS,Z bsf sutats,ac goto FINTER ;***** aiguillage de la fonction ANSI de déplacement du curseur RS2 bcf sutats,ac movlw "A" ;une position vers le haut subwf rxbuf,w btfsc STATUS,Z goto RShaut movlw "B" ;une position vers le bas subwf rxbuf,w btfsc STATUS,Z goto RSbas movlw "C" ;une position vers la droite subwf rxbuf,w btfsc STATUS,Z goto RSdroite movlw "D" ;une position vers la gauche subwf rxbuf,w btfsc STATUS,Z goto RSgauche goto FINTER ;aucune fonction reconnue RShaut movlw .64 ;une position vers le haut subwf pe,f ;indexation dans l'EEPROM btfss STATUS,C goto RS3bas ;si résultat négatif on passe à la ligne du bas movlw low haut ;envoie de la séquence ANSI curseur 1 position vers le haut movwf PTRL movlw high haut movwf PTRH call mes goto FINTER RS3bas movlw low bas3 ;envoie de la séquence ANSI curseur 3 position vers le bas movwf PTRL movlw high bas3 movwf PTRH call mes goto FINTER RSbas movlw .64 ;une position vers le bas addwf pe,f btfsc STATUS,C goto RS3haut movlw low bas movwf PTRL movlw high bas movwf PTRH call mes goto FINTER RS3haut movlw low haut3 movwf PTRL movlw high haut3 movwf PTRH call mes goto FINTER RSdroite incf pe,f ;une position vers la droite btfsc STATUS,Z goto RShome movlw b'00111111' andwf pe,w btfsc STATUS,Z goto RSc1lp1 movlw low droite movwf PTRL movlw high droite movwf PTRH call mes goto FINTER RShome call aL2C1 goto FINTER RSc1lp1 call agauche80b goto FINTER RSgauche movlw .1 ;une position vers la gauche subwf pe,f btfss STATUS,C goto RSend movlw b'00111111' andwf pe,w sublw b'00111111' btfsc STATUS,Z goto RSc63lm1 movlw low gauche movwf PTRL movlw high gauche movwf PTRH call mes goto FINTER RSend call aL5C64 goto FINTER RSc63lm1 movlw low droite63 movwf PTRL movlw high droite63 movwf PTRH call mes movlw low haut movwf PTRL movlw high haut movwf PTRH call mes goto FINTER ;fin de la gestion de l'IT "RCIF" ; timer1 mesure la période d'affichage et stocke la valeur dans atH ath atl avec une précision de 8x272 ns ILS bcf T1CON,TMR1ON ;arrete le timer1 movf TMR1H,w ;sauvegarde de sa valeur movwf ath addwf atH,w btfsc STATUS,Z ;regarde si le timer n'est pas à son tout début ce qui peut goto ILSF ;être la cause d'un rebond de contact de l'ILS (première 05 ms) clrf PB ;on éteint les leds clrf TMR1H ;init timer1 clrf TMR1L bsf T1CON,TMR1ON bcf PIR1,TMR1IF bcf sutats,ov ;gestion et alarme de débordement btfsc sutats,cd bsf sutats,ov ;il y a eu débordement précédement bcf sutats,cd ; pour avoir le temps que doit être afficher un segment de 3mm situé à un rayon de 250 mm : ; 2xPIx250 / 3 = 523 soit à peu près un tour divisé par 512 soit 9 décalages ; mais le rapport des prescalers du timer1/timer0 est de 1/4 soit 2 décalages supplémentaires ; soit 11 décalages pour obtenir la valeur d'attente du timer de segment "TMR0" (timer0) ;ramener à un modulo de 8, 3 décalages seulement sont nécessaire sur atH et TIMR1H rrf atH,f ;3 décalages atH,ath rrf ath,f rrf atH,f rrf ath,f rrf atH,f rrf ath,w movwf atl clrf atH movlw .10 ;test si la durée de la pause est compatible avec la durée minimale d'un segment (87 µs) subwf atl,w ;1 tour = 10 x 512seg x 32 x 217ns = 44 ms btfss STATUS,C ;soit une vitesse max de pi x 26 x 25.4 / 44ms = 47 m/s = 170 km/h bsf sutats,ov ;pour un vélo ce doit être suffisant comf atl,f ;complémente l'attente car le timer0 incrémente sa valeur movf atl,w ;init TMR0 movwf TMR0 bcf INTCON,T0IF bsf sutats,syn ;timer1 synchronnisé sur le milieu du pulse ILS btfss PB,0 ;test si l'ILS n'est plus aimanté goto $-1 bcf T1CON,TMR1ON ;arrete le timer1 btfsc PIR1,TMR1IF ;test si il y a eu un débordement du timer 1 bsf sutats,ov bcf STATUS,C ;divise par 2 la valeur de TMR1 pour centrer le départ sur le pulse de détection rrf TMR1H,f rrf TMR1L,f bsf T1CON,TMR1ON ; l'aimant à une taille de 12mm/3mm = 4 segments ; on lance l'affichage au bout d'un temps correspondant à 4 segments (4xatl) ;on tient compte des prescaler (x8 pour tmr1 et x32 pour timer0) ILS2 swapf atl,w andlw b'00001111' subwf TMR1H,w btfss STATUS,C goto ILS2 ILS3 swapf atl,w andlw b'11110000' subwf TMR1L,w btfss STATUS,C goto ILS3 ILSF bsf T1CON,TMR1ON bcf INTCON,INTF ;fin de la gestion de l'IT "INT" ;***** restauration des registres système FINTER MOVF p_t,w MOVWF PCLATH SWAPF s_t,W ;Swap STATUS_TEMP register into W MOVWF STATUS ;Move W into Status register SWAPF w_t,f ;Swap W_TEMP SWAPF w_t,w ;Swap W_TEMP into W retfie ;****************************** ;* routines / sous programmes * ;****************************** ;*****affiche un message issu de la mem flash en PTRL/H via l'interface série mes call flashr bsf STATUS,RP0 ;bank 1 btfss TXSTA,TRMT ;attend la fin de la transmission en cours goto $-1 bcf STATUS,RP0 ;bank 0 movwf TXREG ;envoie le caractère (qui peut être NULL) movf DATAL,w btfsc STATUS,Z ;test si c'est la fin de la transmission return bsf STATUS,RP0 ;bank 1 btfss TXSTA,TRMT goto $-1 bcf STATUS,RP0 ;bank 0 movwf TXREG incf PTRL,f btfsc STATUS,C incf PTRH,f goto mes ;*****affiche un message issu de l'EEPROM en PTREL/H via l'interface série mese movf PTREL,w call EEPR bsf STATUS,RP0 ;bank 1 btfss TXSTA,TRMT ;attend la fin de la transmission en cours goto $-1 bcf STATUS,RP0 ;bank 0 movwf TXREG ;envoie le caractère (qui peut être NULL) incf PTREL,f movf PTREH,w subwf PTREL,w btfsc STATUS,Z ;test si c'est la fin de la transmission return goto mese ;***** mouvement du curseur ANSI aL2C1 movlw low L2C1 ;curseur en ligne 2 colonne 1 movwf PTRL movlw high L2C1 movwf PTRH call mes return agauche80b movlw low gauche80b ;curseur plus une ligne plus bas en colonne 1 movwf PTRL movlw high gauche80b movwf PTRH call mes return aL5C64 movlw low L5C64 ;curseur en ligne 5 colonne 64 movwf PTRL movlw high L5C64 movwf PTRH call mes return ;***** ecriture de W dans l'EEPROM à l'adresse pe ;>>>disable interupt during call<<< EEPW BSF STATUS,RP1 BSF STATUS,RP0 ;Bank 3 BTFSC EECON1,WR ;Wait for GOTO $-1 ;write to finish BCF STATUS,RP0 ;Bank 2 movf ped,w MOVWF EEDATA ;W is Data to write MOVF pea,W ;Address to MOVWF EEADR ;write to BSF STATUS,RP0 ;Bank 3 BCF EECON1,EEPGD ;Point to Data memory BSF EECON1,WREN ;Enable writes MOVLW 0x55 ;Write 55h to MOVWF EECON2 ;EECON2 MOVLW 0xAA ;Write AAh to MOVWF EECON2 ;EECON2 BSF EECON1,WR ;Start write operation BCF EECON1,WREN ;Disable writes BCF STATUS,RP1 BCF STATUS,RP0 bcf sutats,se return ;***** lecture dans l'EEPROM à l'adresse EEPR BSF STATUS,RP1 BCF STATUS,RP0 ;Bank 2 MOVWF EEADR ;to read from BSF STATUS,RP0 ;Bank 3 BCF EECON1,EEPGD ;Point to Data memory BSF EECON1,RD ;Start read operation BCF STATUS,RP0 ;Bank 2 MOVF EEDATA,W ;W = EEDATA BCF STATUS,RP1 return ;***** lecture de la flash à l'adresse PTRL/H retour dans DATAL et W flashr BSF STATUS,RP1 BCF STATUS,RP0 ;Bank 2 movf PTRL,w ;Write the MOVWF EEADR ;address bytes movf PTRH,w ;for the desired MOVWF EEADRH ;address to read BSF STATUS,RP0 ;Bank 3 BSF EECON1,EEPGD ;Point to Program memory BSF EECON1,RD ;Start read operation NOP ;Required two NOPs NOP BCF STATUS,RP0 ;Bank 2 MOVF EEDATA,W ;DATAL = EEDATA MOVWF DATAL bcf DATAL,7 ;7 bits valides pour ASCII rlf EEDATA,w ;mets le 7ème bit dans C rlf EEDATH,w ;le réintroduit dans le premier caractère bcf STATUS,RP1 return ;********************** ;* debut du programme * ;********************** INIT clrf sutats movlw VPB movwf PB movlw VPC movwf PC bsf STATUS,RP0 movlw TPB movwf TRISB movlw TPC movwf TRISC movlw Voption movwf OPTION_REG bcf STATUS,RP0 ;***** initialisation des périphériques ;***** init RS232 bcf PIR1,RCIF bsf STATUS,RP0 movlw .95 ;14.7456 Mhz 9600 bauds > .95 avec BRGH=1 movwf SPBRG movlw b'00100110' ;CSRC TX9 TXEN SYNC — BRGH TRMT TX9D movwf TXSTA bsf PIE1,RCIE bcf STATUS,RP0 movlw b'10010000' ;SPEN RX9 SREN CREN ADDEN FERR OERR RX9D movwf RCSTA bsf INTCON,PEIE clrf temp ;attente pour la validité de la config clrf temp0 RSd decfsz temp0,f goto RSd decfsz temp,f goto RSd ;*****init TIMER 0 BSF STATUS,RP0 ;Bank 1 movlw b'00000100' ;INT sur front descendant movwf OPTION_REG ;RAPU INTEDG T0CS T0SE PSA PS2 PS1 PS0 BCF STATUS,RP0 ;Bank 0 ;*****init TIMER 1 movlw b'00110001' movwf T1CON ;na na T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON clrf TMR1H ;init timer1 clrf TMR1L bcf PIR1,TMR1IF clrf atH BSF STATUS,RP0 bsf PIE1,TMR1IE ;PSPIE(2) ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE BCF STATUS,RP0 bsf sutats,ov ;***** init INT bcf INTCON,INTF ;GIE PEIE T0IE INTE RBIE T0IF INTF RBIF bsf INTCON,INTE bsf INTCON,PEIE bsf INTCON,GIE ;************************ ;* message de bienvenue * ;************************ movlw low mesdeb movwf PTRL movlw high mesdeb movwf PTRH call mes call aL2C1 ;affiche la totalité de l'EEPROM clrf PTREL movlw .64 movwf PTREH call mese call agauche80b movlw .128 movwf PTREH call mese call agauche80b movlw .192 movwf PTREH call mese call agauche80b clrf PTREH call mese clrf pe ;initialise le curseur d'édition call aL2C1 ;********************* ;* boucle principale * ;********************* B00 movlw .20 ;attente de 20 tours avant le défilement movwf dly clrf offset clrf PB B01 clrf peaf ;adresse du caratere de l'EEPROM à afficher à 0 B0 btfsc sutats,se goto EEP0 btfsc sutats,ov goto B00 btfsc sutats,cd goto B00 movlw high font ;pointeur de l'adresse à affiher à 0 movwf PTRAH movlw low font movwf PTRAL movf peaf,w ;lecture du caratère en EEPROM addwf offset,w ;ajout de l'offset call EEPR movwf temp0 movlw h'20' ;soustraction de l'Ofsset ASCII subwf temp0,f movlw .3 ;multiplication x3 et addition au pointeur de table FLASH movwf temp1 movf temp0,w B1 addwf PTRAL,f btfsc STATUS,C incf PTRAH,f decfsz temp1,f goto B1 movlw .3 ;3 paires de segments à afficher movwf temp2 B4 ;***** lecture d'un segment dans la flash à l'adresse PTRAL/H BSF STATUS,RP1 BCF STATUS,RP0 ;Bank 2 movf PTRAL,w ;Write the MOVWF EEADR ;address bytes movf PTRAH,w ;for the desired MOVWF EEADRH ;address to read BSF STATUS,RP0 ;Bank 3 BSF EECON1,EEPGD ;Point to Program memory BSF EECON1,RD ;Start read operation NOP ;Required two NOPs NOP BCF STATUS,RP0 ;Bank 2 MOVF EEDATA,W ;DATAL = EEDATA MOVWF segh rlf EEDATA,w ;mets le 7ème bit dans C rlf EEDATH,w ;le réintroduit dans le premier caractère movwf segl bcf STATUS,RP1 rlf segh,w B2 btfsc sutats,syn ;test si nouveau tour goto B5 btfss INTCON,T0IF ;attente de la fin de la tempo du TMR0 goto B2 movwf PB ;affiche le segment de poids fort movf atl,w ;init TMR0 movwf TMR0 bcf INTCON,T0IF rlf segl,w B3 btfsc sutats,syn ;test si nouveau tour goto B5 btfss INTCON,T0IF ;attente de la fin de la tempo du TMR0 goto B3 movwf PB ;affiche le segment de poids faible movf atl,w ;init TMR0 movwf TMR0 bcf INTCON,T0IF incf PTRAL,f ;paire de segments suivant btfsc STATUS,Z incf PTRAH,f decfsz temp2,f goto B4 incf peaf,f ;caractère suivant goto B0 B5 bcf sutats,syn ;nouveau tour détecté (syn) decfsz dly,f goto B01 incf dly,f incf offset,f ;au bout de dly tour on augmente l'offset de 1 caractère à chaque tour goto B01 EEP0 bcf INTCON,GIE CALL EEPW bsf INTCON,GIE goto B0 ;*************************************** ;* messages en mémoire programme/FLASH * ;*************************************** ;message de bienvenue mesdeb da "\x1b[40m\x1b[37m\x1b[2JROUELED realisation de messages lumineux sur une roue de VTT\r\n",0 ;sequence ANSI L2C1 da "\x1b[2;1H",0 L5C64 da "\x1b[5;64H",0 haut da "\x1b[A",0 haut3 da "\x1b[3A",0 bas da "\x1b[B",0 bas3 da "\x1b[3B",0 droite da "\x1b[C",0 droite63 da "\x1b[63C",0 gauche da "\x1b[D",0 gauche80b da "\x1b[80D\x1b[B",0 ;*************************************************************** ;* table des segments de caractères en mémoire programme/FLASH * ;*************************************************************** font da h'0',h'0',h'0' ;esp da h'0',h'79',h'0' ;! da h'3800',h'3800',h'0' ;"" da h'3F94',h'3F94',h'14' ;# da h'1512',h'157F',h'24' ;$ da h'3262',h'988',h'23' ;% da h'24B6',h'1155',h'5' ;& da h'2800',h'60',h'0' ;' da h'E00',h'20A2',h'0' ;( da h'2080',h'E22',h'0' ;) da h'414',h'43E',h'14' ;* da h'408',h'47F',h'8' ;+ da h'280',h'6',h'0' ;, da h'408',h'408',h'8' ;- da h'180',h'3',h'0' ;, da h'404',h'1010',h'40' ;/ da h'22BE',h'28C9',h'3E' ;0 da h'1080',h'FF',h'0' ;1 da h'21A1',h'24C5',h'31' ;2 da h'20C2',h'34D1',h'46' ;3 da h'A0C',h'3FA4',h'4' ;4 da h'28F2',h'28D1',h'4E' ;5 da h'149E',h'24C9',h'6' ;6 da h'23C0',h'2848',h'60' ;7 da h'24B6',h'24C9',h'36' ;8 da h'24B0',h'2549',h'3C' ;9 da h'1B00',h'36',h'0' ;: da h'1A80',h'36',h'0' ;; da h'A08',h'20A2',h'0' ;< da h'A14',h'A14',h'14' ;= da h'2080',h'A22',h'8' ;> da h'2020',h'2445',h'30' ;? da h'24A6',h'20CF',h'3E' ;@ da h'223F',h'2244',h'3F' ;A da h'24FF',h'24C9',h'36' ;B da h'20BE',h'20C1',h'22' ;C da h'20FF',h'1141',h'1C' ;D da h'24FF',h'24C9',h'41' ;E da h'247F',h'2448',h'40' ;F da h'20BE',h'24C9',h'2E' ;G da h'47F',h'408',h'7F' ;H da h'2080',h'20FF',h'0' ;I da h'82',h'3F41',h'40' ;J da h'47F',h'1114',h'41' ;K da h'FF',h'81',h'1' ;L da h'107F',h'1018',h'7F' ;M da h'87F',h'208',h'7F' ;N da h'20BE',h'20C1',h'3E' ;O da h'247F',h'2448',h'30' ;P da h'20BE',h'2145',h'3D' ;Q da h'247F',h'254C',h'31' ;R da h'24B1',h'24C9',h'46' ;S da h'2040',h'207F',h'40' ;T da h'FE',h'81',h'7E' ;U da h'17C',h'101',h'7C' ;V da h'FE',h'8F',h'7E' ;W da h'A63',h'A08',h'63' ;X da h'470',h'407',h'70' ;Y da h'22C3',h'28C9',h'61' ;Z da h'3F80',h'20C1',h'0' ;[ da h'820',h'208',h'2' ;\ da h'2080',h'3FC1',h'0' ;] da h'1010',h'1040',h'10' ;^ da h'81',h'81',h'1' ;_ da h'2000',h'820',h'0' ;` da h'A92',h'A95',h'F' ;a da h'2FF',h'489',h'E' ;b da h'88E',h'891',h'2' ;c da h'88E',h'491',h'7F' ;d da h'A8E',h'A95',h'C' ;e da h'1F84',h'2044',h'20' ;f da h'1298',h'12A5',h'1E' ;g da h'47F',h'810',h'F' ;h da h'880',h'DF',h'0' ;i da h'82',h'2F91',h'0' ;j da h'27F',h'88A',h'0' ;k da h'2080',h'FF',h'0' ;l da h'81F',h'80C',h'F' ;m da h'41F',h'810',h'1F' ;n da h'88E',h'891',h'E' ;o da h'A1F',h'A14',h'8' ;p da h'A08',h'A14',h'1F' ;q da h'41F',h'810',h'8' ;r da h'A89',h'A95',h'12' ;s da h'3F10',h'91',h'2' ;t da h'9E',h'101',h'1F' ;u da h'11C',h'101',h'1C' ;v da h'9E',h'86',h'1E' ;w da h'511',h'504',h'11' ;x da h'298',h'285',h'1E' ;y da h'991',h'C95',h'11' ;z da h'400',h'20B6',h'0' ;{ da h'0',h'7F',h'0' ;| da h'2080',h'436',h'0' ;} da h'808',h'208',h'8' ;~ da h'3FFF',h'3FFF',h'7F' ;del end