]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - pruebas/sdcc/leds_asm/leds.asm
Hago directorio para ir poniendo versiones funcionales.
[z.facultad/66.09/etherled.git] / pruebas / sdcc / leds_asm / leds.asm
index 5fd53140033f276e11bcc6dede544e508445105e..bc729f119f8ad42b40793e2e657a8fd8542f2848 100644 (file)
@@ -4,25 +4,30 @@
 .module     leds
 .optsdcc    -mmcs51 --model-small
 
-; Variables globales
-.globl  _leds_matrix
-.globl  _leds_matrix_len
-.globl  _leds_delay
-
-; Funciones globales
-.globl  _leds_init
-.globl  _leds_write
-.globl  _leds_write0
-.globl  _leds_write1
-.globl  _leds_delay_update
+; Constantes "públicas"
+LEDS_MAX_COLS    = 32       ; Cantidad máxima de columnas
+
+; Variables públicas
+.globl  _leds_matrix_len    ; unsigned char
+.globl  _leds_matrix        ; unsigned int[LEDS_MAX_COLS]
+.globl  _leds_delay         ; unsigned char
+
+; Funciones públicas
+.globl  _leds_init          ; void leds_init();
+.globl  _leds_test          ; void leds_test();
+.globl  _leds_write         ; void leds_write(unsigned int);
+.globl  _leds_write_low     ; void leds_write_low(unsigned char);
+.globl  _leds_write_high    ; void leds_write_high(unsigned char);
+.globl  _leds_delay_update  ; void leds_delay_update();
+.globl  _leds_timer2_isr    ; void leds_timer2_isr() interrupt 5;
+
 
 ; Constantes
 ; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
-INTERVAL        = 66 ; 0.1ms (por el clock de 8MHz)
-LEDS0           = 0x0080
-LEDS1           = 0x00c0
-MAX_COLS        = 64
-DELAY_BASE      = 28
+INTERVAL        = 33 ; 0.05ms (por el clock de 8MHz)
+LEDS_HIGH       = 0x0080
+LEDS_LOW        = 0x00c0
+DELAY_BASE      = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20
 
 ; Área de bancos de registros
 .area   REG_BANK_0    (REL,OVR,DATA)
@@ -46,23 +51,18 @@ _leds_delay::
 delay:
     .ds     1
 curr_col:
-__stack:  ; XXX
-    .ds     1
 
 ; Variables en memoria RAM extendida indirecta (8052)
 .area   ISEG    (DATA)
 _leds_matrix::
-    .ds     MAX_COLS * 2  ; 2 bytes por columna
+    .ds     LEDS_MAX_COLS * 2  ; 2 bytes por columna
 
 
 ; Configuramos el vector de interrupciones para atender el timer2
-.area   INTV    (ABS, CODE)
-    .org    0x0000     ; XXX
-    ljmp    _leds_init ; XXX
-
-    .org    0x002b
-    clr     tf2 ; limpio bit de interrupción porque para el timer2 no es autom.
-    ljmp    timer2_isr
+;.area   INTV    (ABS, CODE)
+;    .org    0x002b
+;    clr     tf2 ; limpio bit de interrupción porque para el timer2 no es autom.
+;    ljmp    timer2_isr
 
 
 ; Área de código del programa
@@ -74,14 +74,13 @@ _leds_matrix::
 ;
 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
 _leds_init::
-    mov     sp, #__stack ; XXX
     ; guardo registros que uso
     push    ar0
     push    ar1
     push    ar2
 
     ; leo de la ROM el tamaño por default
-    mov     dptr, #MAT_D_LEN
+    mov     dptr, #DEFAULT_MATRIX_LEN
     clr     a
     movc    a, @a+dptr
     mov     _leds_matrix_len, a
@@ -94,66 +93,94 @@ _leds_init::
     mov     delay, _leds_delay
 
     ; copio imagen por default de la ROM a la RAM
-    mov     dptr, #MAT_D
+    mov     dptr, #DEFAULT_MATRIX
     mov     r0, #0              ; indice del "array" en la ROM
     mov     r1, #_leds_matrix   ; dirección de memoria de la RAM
     mov     a, r0
-seguir$:
+proximo$:
     movc    a, @a+dptr         ; leo de la ROM con el índice
     mov     @r1, a ; escribo en el puntero a la RAM
     inc     r1 ; incremento puntero
     inc     r0 ; incremento índice
     mov     a, r0 ; para comparar
-    cjne    a, ar2, seguir$ ; veo si quedan más bytes por leer
+    cjne    a, ar2, proximo$ ; veo si quedan más bytes por leer
 
     ; cargo los capture registers
     mov     rcap2l, #<(-INTERVAL) ; low byte del intervalo
     mov     rcap2h, #>(-INTERVAL) ; high byte del intervalo
 
-    mov     ie, #0b10100000 ; habilito interrupcion timer 2
-                            ; bits de IE (interrupt enable) en 1:
-                            ; IE.7 (Global enable/disable)
-                            ; IE.5 (Enable timer 2 interrupt)
-    mov     t2con, #0b00000100 ; setup timer 2 (auto-reload y start)
+    mov     t2con, #0x00; setup del timer2 (auto-reload), no lo arrancamos
+    setb    et2 ; habilito interrupcion timer2 (IE.5)
 
     mov     curr_col, #0  ; inicializo el contador de columna en 0
 
     ; Limpiamos stack
-    push    ar2
-    push    ar1
-    push    ar0
+    pop     ar2
+    pop     ar1
+    pop     ar0
 
     ret
 
 
+; Hace una prueba simple de los leds
+; Primitiva de C:
+;                   void leds_test();
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_test::
+    ; escribo patrones en los leds
+    mov     dptr, #0xffff
+    acall   _leds_write
+    acall   sleep
+
+    mov     dptr, #0xaaaa
+    acall   _leds_write
+    acall   sleep
+    
+    mov     dptr, #0x5555
+    acall   _leds_write
+    acall   sleep
+
+    mov     dptr, #0x0000
+    acall   _leds_write
+    acall   sleep
+    
+    ret    
+
+
 ; Escribe en los leds.
 ; Primitiva de C:
 ;                   void leds_write(unsigned int);
 ;
 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
 _leds_write::
+    ; guardamos en r0 la parte alta que imprimimos despues
+    push    ar0
+    mov     r0, dph
     ; parte baja
     mov     a, dpl ; de C me viene la parte baja del argumento en el dpl
-    mov     dptr, #LEDS0
+    mov     dptr, #LEDS_LOW
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
     ; parte alta
-    mov     a, dph ; de C me viene la parte alta del argumento en el dph
-    mov     dptr, #LEDS1
+    mov     a, r0 ; de C me viene la parte alta del argumento en el dph
+    mov     dptr, #LEDS_HIGH
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
+    ; devolvemos r0
+    pop     ar0
     ret
 
 
 ; Escribe en los leds del primer latch.
 ; Primitiva de C:
-;                   void leds_write0(unsigned char);
+;                   void leds_write_low(unsigned char);
 ;
 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
-_leds_write0::
+_leds_write_low::
     ; parte baja
     mov     a, dpl       ; de C me viene el argumento en el dpl
-    mov     dptr, #LEDS0
+    mov     dptr, #LEDS_LOW
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
     ret
@@ -161,13 +188,13 @@ _leds_write0::
 
 ; Escribe en los leds del segundo latch.
 ; Primitiva de C:
-;                   void leds_write1(unsigned char);
+;                   void leds_write_high(unsigned char);
 ;
 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
-_leds_write1::
+_leds_write_high::
     ; parte baja
     mov     a, dpl       ; de C me viene el argumento en el dpl
-    mov     dptr, #LEDS1
+    mov     dptr, #LEDS_HIGH
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
     ret
@@ -190,10 +217,13 @@ _leds_delay_update::
     ret
     
 
-; Manejador de la interrupción del timer2
-timer2_isr:
+; Manejador de la interrupción del timer2 para el uso de los leds.
+; Primitiva de C:
+;                   void leds_timer2_isr() interrupt 5;
+;
+_leds_timer2_isr::
     ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
-    djnz    delay, fin$
+    djnz    delay, 255$
 
     ; comenzamos realmente a leer la próxima columna
     mov     delay, _leds_delay
@@ -207,13 +237,13 @@ timer2_isr:
 
     ; vemos si hay que empezar a leer por la 1ra columna de nuevo
     mov     a, curr_col
-    cjne    a, _leds_matrix_len, continua$
+    cjne    a, _leds_matrix_len, 1$
     
     ; hay que empezar de nuevo
     mov     curr_col, #0
     mov     a, curr_col ; dejamos en a la columna actual
 
-continua$:
+1$:
     ; multiplicamos por 2 porque hay 2 bytes por columna
     clr     c
     rlc     a                   
@@ -223,16 +253,16 @@ continua$:
     add     a, r0 ; le sumo al puntero el offset actual segun la columna
     mov     r0, a
 
-    ; imprimo en LEDS1
+    ; imprimo en LEDS_LOW
     mov     a, @r0 ; leo el contenido de la matriz
-    mov     dptr, #LEDS1
+    mov     dptr, #LEDS_LOW
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
 
-    ; imprimo en LEDS0
+    ; imprimo en LEDS_HIGH
     inc     r0     ; busco proximo byte de la columna
     mov     a, @r0 ; leo el contenido de la matriz
-    mov     dptr, #LEDS0
+    mov     dptr, #LEDS_HIGH
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
 
@@ -248,16 +278,30 @@ continua$:
     pop     psw
     pop     acc
 
-fin$:
+255$:
     reti ; listo! seguimos viaje...
 
 
+; Provoca un retardo corto.
+; Usamos dpl y dph porque son "C-safe".
+sleep:
+    mov     a, #0xff
+2$:
+    mov     dph, #0xff
+1$:
+    mov     dpl, #0xff
+    djnz    dpl, .
+    djnz    dph, 1$
+    djnz    acc, 2$
+    ret
+
+
 ; Matriz por default
-MAT_D_LEN:
+DEFAULT_MATRIX_LEN:
     .db     16
     ;.db     32
 
-MAT_D:
+DEFAULT_MATRIX:
     .dw     0b0000111111110000    ; columna 0
     .dw     0b0011111111111100    ; columna 1
     .dw     0b0111000000001110    ; columna 2
@@ -275,24 +319,23 @@ MAT_D:
     .dw     0b0011111111111100    ; columna 14
     .dw     0b0000111111110000    ; columna 15
 
-;    .dw     0b0000111111110000    ; columna 0
-;    .dw     0b0011111111111100    ; columna 1
-;    .dw     0b0111000000001110    ; columna 2
-;    .dw     0b0110000000000110    ; columna 3
-;    .dw     0b1100110000000011    ; columna 4
-;    .dw     0b1100011000110011    ; columna 5
-;    .dw     0b1100001100110011    ; columna 6
-;    .dw     0b1100001100000011    ; columna 7
-;    .dw     0b1100001100000011    ; columna 8
-;    .dw     0b1100001100110011    ; columna 9
-;    .dw     0b1100011000110011    ; columna 10
-;    .dw     0b1100110000000011    ; columna 11
-;    .dw     0b0110000000000110    ; columna 12
-;    .dw     0b0111000000001110    ; columna 13
-;    .dw     0b0011111111111100    ; columna 14
-;    .dw     0b0000111111110000    ; columna 15
-
-;MAT_D:
+    .dw     0b1111000000001111    ; columna 0
+    .dw     0b1100000000000011    ; columna 1
+    .dw     0b1000111111110001    ; columna 2
+    .dw     0b1001111111111001    ; columna 3
+    .dw     0b0011001111111100    ; columna 4
+    .dw     0b0011100111001100    ; columna 5
+    .dw     0b0011110011001100    ; columna 6
+    .dw     0b0011110011111100    ; columna 7
+    .dw     0b0011110011111100    ; columna 8
+    .dw     0b0011110011001100    ; columna 9
+    .dw     0b0011100111001100    ; columna 01
+    .dw     0b0011001111111100    ; columna 00
+    .dw     0b1001111111111001    ; columna 01
+    .dw     0b1000111111110001    ; columna 03
+    .dw     0b1100000000000011    ; columna 04
+    .dw     0b1111000000001111    ; columna 05
+
 ;    .dw     0b0000001111100000    ; columna 0
 ;    .dw     0b0000111110000000    ; columna 1
 ;    .dw     0b0111111000000000    ; columna 2