/*---------------------------------------------*/ /* Jan Dvořák (dvoraj19) ÚT 11:00 (3.12.2008) */ /*---------------------------------------------*/ .org 0x0000 .include "m169def.inc" start: ;zásobník ldi r16, 0 out SPL, r16 ldi r16, 0x04 out SPH, r16 ;iniciaizace call init_disp call smaz_disp ; /* DEMONSTRACE FUNKCE ZOBRAZ_ZNAK */ /* ;zobrazení znaku: r16 znak; r17 pozice ldi r16, '<' ldi r17, 1 call zobraz_znak ldi r16, 'T' ldi r17, 2 call zobraz_znak ldi r16, 'E' ldi r17, 3 call zobraz_znak ldi r16, 'X' ldi r17, 4 call zobraz_znak ldi r16, 'T' ldi r17, 5 call zobraz_znak ldi r16, '>' ldi r17, 6 call zobraz_znak */ /* DEMONSTRACE FUNKCE ZOBRAZ_CISLO */ ;/* ;číslo: R16 call smaz_disp ldi r16, 76 call zobraz_cislo ;*/ ;konec programu rjmp end /*----------------------------------*/ /* Inicializuj display */ /*----------------------------------*/ init_disp: ldi r16, 0xB7 sts LCDCRB, r16 ldi r16, 0x10 sts LCDFRR, r16 ldi r16, 0x0F sts LCDCCR, r16 ldi r16, 0x80 sts LCDCRA, r16 ret /*----------------------------------*/ /* Smazat display */ /*----------------------------------*/ smaz_disp: ldi r16,0 ;pozice 1 2 sts LCDDR0, r16 sts LCDDR0 + 5, r16 sts LCDDR0 + 10, r16 sts LCDDR0 + 15, r16 ;pozice 3 4 sts LCDDR1, r16 sts LCDDR1 + 5, r16 sts LCDDR1 + 10, r16 sts LCDDR1 + 15, r16 ;pozice 5 6 sts LCDDR2, r16 sts LCDDR2 + 5, r16 sts LCDDR2 + 10, r16 sts LCDDR2 + 15, r16 ;ostatni segmenty sts LCDDR3, r16 sts LCDDR3 + 5, r16 sts LCDDR3 + 10, r16 sts LCDDR3 + 15, r16 ret /*----------------------------------*/ /* Zobrazit znak ASCII */ /*----------------------------------*/ zobraz_znak: ;používám R16-R21, R0, R26 R27(X) R30 R31(Z) ;zobrazení znaku: r16 znak; r17 pozice ;pomocné proměné - zachování pvodních v zásobíku push r0 push r18 push r19 push r20 push r21 push r26 push r27 push r30 push r31 ;výpočet znaku (4*ASC()-42) subi r16, 42 lsl r16 lsl r16 ;výpočet pozice ;odečteme 1, vydělíme 2 - display po 2 znacích, zjistíme levou - pravou pozici ldi r19,0 ;R19 : levost pravost uložení informace dec r17 lsr r17 ;určení vlevo - v pravo-carry bit při dělení dvěma - liché číslo; brcc preskoc ldi r19, 1 ; informace o pozici segmentu preskoc: ;adresa na display ldi r26,LCDDR0; X registr clr r27 ; jen tak pro jistotu add r26,r17 ;pozice ;načtení znaků - registr Z ldi r30, low(znaky<<1) ldi r31, high(znaky<<1) add r30, r16; přesun na pozici znaku ;provedeme cyklus ve kterém načteme data z druhého segmentu ;a přidáme data nová, posuneme se na další řádek ldi r21, 4; cyklus: ;LCDR ld r18, X; načteme aktuální stav a vynulujeme příslušné byty - horní nebo dolní lpm r20, Z+ ; načteme z registru Z, zvětšíme o 1 - posun na další čtveřici v souboru subi r19, 0; kontrola R19 - jestli byl carry bit v dělení - pravost levost breq neposun posun: ;posun o 4 bity - levý segment lsl r20 lsl r20 lsl r20 lsl r20 ;vynulujem horní byty andi r18, 0b00001111 jmp pokracuj neposun: andi r18, 0b11110000 ;nulujeme spodní byty pokracuj: add r18, r20 mov r0, r18 st X, r0 adiw r26,5 ; posun v registru dec r21 ;správa cyklu brne cyklus; pokračuejem v cyklu dokud r21 není nula ;navrácení hodnot do záobníku registrům pop r31 pop r30 pop r27 pop r26 pop r21 pop r20 pop r19 pop r18 pop r0 ret /*----------------------------------*/ /* Zobraz číslo */ /*----------------------------------*/ zobraz_cislo: ;číslo z regitru R16; další používané R17, R18 ;rozdělíme výpočet na výpočet stovek, desítek a jednotek, pak pomocí ;zobraz znak zobazíme na display (zobrazujeme zprava) push r17; uchování registrů push r18 ;stovky ldi r17, 100 call vydel_cisla ; výsledek v R16, zbytek R17 mov r18, r17 ; uchování zbytku ;mod nezobrazuj nuly, pokud zapoznámkujeme řádky s hvězdičkama, zobrazíme nuly brne mod2a ;*********************** ldi r16, '@' ;*********************** jmp mod2b ;*********************** mod2a: ;*********************** subi r16, 16 ; výpočet hodnoty pro zobrazznak (ASCII) mod2b: ;*********************** ldi r17, 4 call zobraz_znak ;desítky ldi r17, 10 mov r16, r18 call vydel_cisla mov r18, r17 ;mod nezobrazuj nuly brne mod2aa ;*********************** ldi r16, '@' ;*********************** jmp mod2ab ;*********************** mod2aa: ;*********************** subi r16, 16 ; výpočet hodnoty pro zobrazznak (ASCII) mod2ab: ;*********************** ldi r17, 5 call zobraz_znak ;jednotky mov r16, r18; přesun zbytku po delení 10 ldi r17, 6 subi r16, 16 ; výpočet hodnoty pro zobrazznak (ASCII) call zobraz_znak ;navrácení registrům pvodní hodnoty pop r18 pop r17 ; ret /*----------------------------------*/ /* Vyděl čísla */ /*----------------------------------*/ vydel_cisla: ;číslo z registru 16 čílem z registru 17 ;výsledek: r16 ;používané registry: R18, R19 push r18 ; uchování v zásobníku push r19; zbytek po deleni ldi r18, 8; 8 bitová čísla - režije cyklu ldi r19, 0 lsl r16 ; posun o byt - vynásobení 2 cyklus_del: rol r19 cp r19, r17 brlo del_preskoc sub r19, r17 del_preskoc: rol r16 dec r18 brne cyklus_del com r16 mov r17, r19 ;promenné ze zásobníku pop r19 pop r18 ; ret /*----------------------------------*/ end: rjmp end .include "znaky.inc"