]> git.llucax.com Git - z.facultad/66.09/etherled.git/blob - pruebas/sdcc/leds_asm/leds.asm
Agrego ejemplo de los leds andando escrito en ASM para sdcc. Falta hacer el .h
[z.facultad/66.09/etherled.git] / pruebas / sdcc / leds_asm / leds.asm
1 ; vim: set filetype=asx8051 et sw=4 sts=4 :
2
3 ; Módulo y opciones
4 .module     leds
5 .optsdcc    -mmcs51 --model-small
6
7 ; Variables globales
8 .globl  _leds_matrix
9 .globl  _leds_matrix_len
10 .globl  _leds_delay
11
12 ; Funciones globales
13 .globl  _leds_init
14 .globl  _leds_write
15 .globl  _leds_write0
16 .globl  _leds_write1
17 .globl  _leds_delay_update
18
19 ; Constantes
20 ; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
21 INTERVAL        = 66 ; 0.1ms (por el clock de 8MHz)
22 LEDS0           = 0x0080
23 LEDS1           = 0x00c0
24 MAX_COLS        = 64
25 DELAY_BASE      = 28
26
27 ; Área de bancos de registros
28 .area   REG_BANK_0    (REL,OVR,DATA)
29     .ds     8
30     ; Usamos siempre banco 0
31     ar0     = 0x00
32     ar1     = 0x01
33     ar2     = 0x02
34     ar3     = 0x03
35     ar4     = 0x04
36     ar5     = 0x05
37     ar6     = 0x06
38     ar7     = 0x07
39
40 ; Variables es memoria RAM común
41 .area   DSEG    (DATA)
42 _leds_matrix_len::
43     .ds     1
44 _leds_delay::
45     .ds     1
46 delay:
47     .ds     1
48 curr_col:
49 __stack:  ; XXX
50     .ds     1
51
52 ; Variables en memoria RAM extendida indirecta (8052)
53 .area   ISEG    (DATA)
54 _leds_matrix::
55     .ds     MAX_COLS * 2  ; 2 bytes por columna
56
57
58 ; Configuramos el vector de interrupciones para atender el timer2
59 .area   INTV    (ABS, CODE)
60     .org    0x0000     ; XXX
61     ljmp    _leds_init ; XXX
62
63     .org    0x002b
64     clr     tf2 ; limpio bit de interrupción porque para el timer2 no es autom.
65     ljmp    timer2_isr
66
67
68 ; Área de código del programa
69 .area   CSEG    (CODE)
70
71 ; Inicializa leds.
72 ; Primitiva de C:
73 ;                   void leds_init();
74 ;
75 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
76 _leds_init::
77     mov     sp, #__stack ; XXX
78     ; guardo registros que uso
79     push    ar0
80     push    ar1
81     push    ar2
82
83     ; leo de la ROM el tamaño por default
84     mov     dptr, #MAT_D_LEN
85     clr     a
86     movc    a, @a+dptr
87     mov     _leds_matrix_len, a
88     clr     c
89     rlc     a ; multiplicamos por 2 porque hay 2 bytes por columna
90     mov     r2, a ; tamaño en bytes de la matriz
91
92     ; Cargo milisegundos
93     acall   _leds_delay_update
94     mov     delay, _leds_delay
95
96     ; copio imagen por default de la ROM a la RAM
97     mov     dptr, #MAT_D
98     mov     r0, #0              ; indice del "array" en la ROM
99     mov     r1, #_leds_matrix   ; dirección de memoria de la RAM
100     mov     a, r0
101 seguir$:
102     movc    a, @a+dptr         ; leo de la ROM con el índice
103     mov     @r1, a ; escribo en el puntero a la RAM
104     inc     r1 ; incremento puntero
105     inc     r0 ; incremento índice
106     mov     a, r0 ; para comparar
107     cjne    a, ar2, seguir$ ; veo si quedan más bytes por leer
108
109     ; cargo los capture registers
110     mov     rcap2l, #<(-INTERVAL) ; low byte del intervalo
111     mov     rcap2h, #>(-INTERVAL) ; high byte del intervalo
112
113     mov     ie, #0b10100000 ; habilito interrupcion timer 2
114                             ; bits de IE (interrupt enable) en 1:
115                             ; IE.7 (Global enable/disable)
116                             ; IE.5 (Enable timer 2 interrupt)
117     mov     t2con, #0b00000100 ; setup timer 2 (auto-reload y start)
118
119     mov     curr_col, #0  ; inicializo el contador de columna en 0
120
121     ; Limpiamos stack
122     push    ar2
123     push    ar1
124     push    ar0
125
126     ret
127
128
129 ; Escribe en los leds.
130 ; Primitiva de C:
131 ;                   void leds_write(unsigned int);
132 ;
133 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
134 _leds_write::
135     ; parte baja
136     mov     a, dpl ; de C me viene la parte baja del argumento en el dpl
137     mov     dptr, #LEDS0
138     cpl     a ; complemento para ver encendidos los "1"
139     movx    @dptr, a
140     ; parte alta
141     mov     a, dph ; de C me viene la parte alta del argumento en el dph
142     mov     dptr, #LEDS1
143     cpl     a ; complemento para ver encendidos los "1"
144     movx    @dptr, a
145     ret
146
147
148 ; Escribe en los leds del primer latch.
149 ; Primitiva de C:
150 ;                   void leds_write0(unsigned char);
151 ;
152 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
153 _leds_write0::
154     ; parte baja
155     mov     a, dpl       ; de C me viene el argumento en el dpl
156     mov     dptr, #LEDS0
157     cpl     a ; complemento para ver encendidos los "1"
158     movx    @dptr, a
159     ret
160
161
162 ; Escribe en los leds del segundo latch.
163 ; Primitiva de C:
164 ;                   void leds_write1(unsigned char);
165 ;
166 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
167 _leds_write1::
168     ; parte baja
169     mov     a, dpl       ; de C me viene el argumento en el dpl
170     mov     dptr, #LEDS1
171     cpl     a ; complemento para ver encendidos los "1"
172     movx    @dptr, a
173     ret
174
175
176 ; Actualiza el retardo de la matriz según la cantidad de columnas
177 ; Primitiva de C:
178 ;                   void leds_delay_update();
179 ;
180 ; La fórmula utilizada es: (DELAY_BASE - (leds_matrix_len / 2)) * 0.1 ms
181 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
182 _leds_delay_update::
183     mov     a, _leds_matrix_len
184     clr     c
185     rrc     a ; divido por 2
186     mov     dpl, a
187     mov     a, #DELAY_BASE
188     subb    a, dpl
189     mov     _leds_matrix_len, a
190     ret
191     
192
193 ; Manejador de la interrupción del timer2
194 timer2_isr:
195     ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
196     djnz    delay, fin$
197
198     ; comenzamos realmente a leer la próxima columna
199     mov     delay, _leds_delay
200
201     ; guardamos en el stack el estado actual de los registros que vamos a usar
202     push    acc
203     push    psw
204     push    ar0
205     push    dpl
206     push    dph
207
208     ; vemos si hay que empezar a leer por la 1ra columna de nuevo
209     mov     a, curr_col
210     cjne    a, _leds_matrix_len, continua$
211     
212     ; hay que empezar de nuevo
213     mov     curr_col, #0
214     mov     a, curr_col ; dejamos en a la columna actual
215
216 continua$:
217     ; multiplicamos por 2 porque hay 2 bytes por columna
218     clr     c
219     rlc     a                   
220
221     ; uso r0 como puntero al comienzo de la matriz
222     mov     r0, #_leds_matrix
223     add     a, r0 ; le sumo al puntero el offset actual segun la columna
224     mov     r0, a
225
226     ; imprimo en LEDS1
227     mov     a, @r0 ; leo el contenido de la matriz
228     mov     dptr, #LEDS1
229     cpl     a ; complemento para ver encendidos los "1"
230     movx    @dptr, a
231
232     ; imprimo en LEDS0
233     inc     r0     ; busco proximo byte de la columna
234     mov     a, @r0 ; leo el contenido de la matriz
235     mov     dptr, #LEDS0
236     cpl     a ; complemento para ver encendidos los "1"
237     movx    @dptr, a
238
239     ; avanzamos a la proxima columna
240     mov     a, curr_col
241     inc     a
242     mov     curr_col, a
243
244     ; sacamos nuestra basura del stack
245     pop     dph
246     pop     dpl
247     pop     ar0
248     pop     psw
249     pop     acc
250
251 fin$:
252     reti ; listo! seguimos viaje...
253
254
255 ; Matriz por default
256 MAT_D_LEN:
257     .db     16
258     ;.db     32
259
260 MAT_D:
261     .dw     0b0000111111110000    ; columna 0
262     .dw     0b0011111111111100    ; columna 1
263     .dw     0b0111000000001110    ; columna 2
264     .dw     0b0110000000000110    ; columna 3
265     .dw     0b1100001100000011    ; columna 4
266     .dw     0b1100011000110011    ; columna 5
267     .dw     0b1100110000110011    ; columna 6
268     .dw     0b1100110000000011    ; columna 7
269     .dw     0b1100110000000011    ; columna 8
270     .dw     0b1100110000110011    ; columna 9
271     .dw     0b1100011000110011    ; columna 10
272     .dw     0b1100001100000011    ; columna 11
273     .dw     0b0110000000000110    ; columna 12
274     .dw     0b0111000000001110    ; columna 13
275     .dw     0b0011111111111100    ; columna 14
276     .dw     0b0000111111110000    ; columna 15
277
278 ;    .dw     0b0000111111110000    ; columna 0
279 ;    .dw     0b0011111111111100    ; columna 1
280 ;    .dw     0b0111000000001110    ; columna 2
281 ;    .dw     0b0110000000000110    ; columna 3
282 ;    .dw     0b1100110000000011    ; columna 4
283 ;    .dw     0b1100011000110011    ; columna 5
284 ;    .dw     0b1100001100110011    ; columna 6
285 ;    .dw     0b1100001100000011    ; columna 7
286 ;    .dw     0b1100001100000011    ; columna 8
287 ;    .dw     0b1100001100110011    ; columna 9
288 ;    .dw     0b1100011000110011    ; columna 10
289 ;    .dw     0b1100110000000011    ; columna 11
290 ;    .dw     0b0110000000000110    ; columna 12
291 ;    .dw     0b0111000000001110    ; columna 13
292 ;    .dw     0b0011111111111100    ; columna 14
293 ;    .dw     0b0000111111110000    ; columna 15
294
295 ;MAT_D:
296 ;    .dw     0b0000001111100000    ; columna 0
297 ;    .dw     0b0000111110000000    ; columna 1
298 ;    .dw     0b0111111000000000    ; columna 2
299 ;    .dw     0b1111000000000000    ; columna 3
300 ;    .dw     0b0111100000000000    ; columna 4
301 ;    .dw     0b0011110000000000    ; columna 5
302 ;    .dw     0b0001111000000000    ; columna 6
303 ;    .dw     0b0000111100000000    ; columna 7
304 ;    .dw     0b0000011110000000    ; columna 8
305 ;    .dw     0b0000001111000000    ; columna 9
306 ;    .dw     0b0000000111100000    ; columna 10
307 ;    .dw     0b0000000011110000    ; columna 11
308 ;    .dw     0b0000000001111000    ; columna 12
309 ;    .dw     0b0000000000111100    ; columna 13
310 ;    .dw     0b0000000000011110    ; columna 14
311 ;    .dw     0b0000000000001111    ; columna 15
312
313 ;end