1 ; vim: set filetype=asx8051 et sw=4 sts=4 :
5 .optsdcc -mmcs51 --model-small
9 .globl _leds_matrix_len
17 .globl _leds_delay_update
20 ; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
21 INTERVAL = 66 ; 0.1ms (por el clock de 8MHz)
27 ; Área de bancos de registros
28 .area REG_BANK_0 (REL,OVR,DATA)
30 ; Usamos siempre banco 0
40 ; Variables es memoria RAM común
52 ; Variables en memoria RAM extendida indirecta (8052)
55 .ds MAX_COLS * 2 ; 2 bytes por columna
58 ; Configuramos el vector de interrupciones para atender el timer2
59 .area INTV (ABS, CODE)
64 clr tf2 ; limpio bit de interrupción porque para el timer2 no es autom.
68 ; Área de código del programa
75 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
77 mov sp, #__stack ; XXX
78 ; guardo registros que uso
83 ; leo de la ROM el tamaño por default
87 mov _leds_matrix_len, a
89 rlc a ; multiplicamos por 2 porque hay 2 bytes por columna
90 mov r2, a ; tamaño en bytes de la matriz
93 acall _leds_delay_update
94 mov delay, _leds_delay
96 ; copio imagen por default de la ROM a la RAM
98 mov r0, #0 ; indice del "array" en la ROM
99 mov r1, #_leds_matrix ; dirección de memoria de la RAM
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
109 ; cargo los capture registers
110 mov rcap2l, #<(-INTERVAL) ; low byte del intervalo
111 mov rcap2h, #>(-INTERVAL) ; high byte del intervalo
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)
119 mov curr_col, #0 ; inicializo el contador de columna en 0
129 ; Escribe en los leds.
131 ; void leds_write(unsigned int);
133 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
136 mov a, dpl ; de C me viene la parte baja del argumento en el dpl
138 cpl a ; complemento para ver encendidos los "1"
141 mov a, dph ; de C me viene la parte alta del argumento en el dph
143 cpl a ; complemento para ver encendidos los "1"
148 ; Escribe en los leds del primer latch.
150 ; void leds_write0(unsigned char);
152 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
155 mov a, dpl ; de C me viene el argumento en el dpl
157 cpl a ; complemento para ver encendidos los "1"
162 ; Escribe en los leds del segundo latch.
164 ; void leds_write1(unsigned char);
166 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
169 mov a, dpl ; de C me viene el argumento en el dpl
171 cpl a ; complemento para ver encendidos los "1"
176 ; Actualiza el retardo de la matriz según la cantidad de columnas
178 ; void leds_delay_update();
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.
183 mov a, _leds_matrix_len
189 mov _leds_matrix_len, a
193 ; Manejador de la interrupción del timer2
195 ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
198 ; comenzamos realmente a leer la próxima columna
199 mov delay, _leds_delay
201 ; guardamos en el stack el estado actual de los registros que vamos a usar
208 ; vemos si hay que empezar a leer por la 1ra columna de nuevo
210 cjne a, _leds_matrix_len, continua$
212 ; hay que empezar de nuevo
214 mov a, curr_col ; dejamos en a la columna actual
217 ; multiplicamos por 2 porque hay 2 bytes por columna
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
227 mov a, @r0 ; leo el contenido de la matriz
229 cpl a ; complemento para ver encendidos los "1"
233 inc r0 ; busco proximo byte de la columna
234 mov a, @r0 ; leo el contenido de la matriz
236 cpl a ; complemento para ver encendidos los "1"
239 ; avanzamos a la proxima columna
244 ; sacamos nuestra basura del stack
252 reti ; listo! seguimos viaje...
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
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
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