-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake_game.asm
935 lines (905 loc) · 28.6 KB
/
snake_game.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
;****************************************************************************************************************************************************
;****************************************************************************************************************************************************
; AUTORES: Franco Riba y Kevil Walter Reynoso Choque
; FECHA: 08/06/2022
; HARDWARE: PIC16F887
; DESCRIPCIÓN: Videojuego Snake con display en matriz 8x8, programado en lenguaje ensamblador
; CONTEXTO: Este es el proyecto integrador de fin de curso de la asignatura Electrónica Digital 2, de la FCEFyN, Universidad Nacional de Córdoba, UNC
;*****************************************************************************************************************************************************
;*****************************************************************************************************************************************************
;-------------------------------------------------------------------------------
;----------------------------- Precompilación --------------------------------
;-------------------------------------------------------------------------------
LIST P = 16F887, R=DEC
include <P16F887.inc>
__CONFIG _CONFIG1, _INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
__CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF
;-------------------------------------------------------------------------------
;----------------------------- Descripción de Puertos en Hardware ------------
;-------------------------------------------------------------------------------
; PORTD - Salida - RD0 - Pin 19 - Row 1
; PORTD - Salida - RD1 - Pin 20 - Row 2
; PORTD - Salida - RD2 - Pin 21 - Row 3
; PORTD - Salida - RD3 - Pin 22 - Row 4
; PORTD - Salida - RD4 - Pin 27 - Row 5
; PORTD - Salida - RD5 - Pin 28 - Row 6
; PORTD - Salida - RD6 - Pin 29 - Row 7
; PORTD - Salida - RD7 - Pin 30 - Row 7
; PORTC - Salida - RC0 - Pin 15 - Column 1
; PORTC - Salida - RC1 - Pin 16 - Column 2
; PORTC - Salida - RC2 - Pin 17 - Column 3
; PORTC - Salida - RC3 - Pin 18 - Column 4
; PORTC - Salida - RC4 - Pin 23 - Column 5
; PORTC - Salida - RC5 - Pin 24 - Column 6
; PORTC - Salida - RB2 - Pin 25 - Column 7
; PORTC - Salida - RB3 - Pin 26 - Column 8
; PORTB - Entrada - RB7 - Pin 40 - Botón DOWN
; PORTB - Entrada - RB6 - Pin 39 - Botón UP
; PORTB - Entrada - RB5 - Pin 38 - Botón LEFT
; PORTB - Entrada - RB4 - Pin 37 - Botón RIGHT
;-------------------------------------------------------------------------------
;-------------------------------- Variables ----------------------------------
;-------------------------------------------------------------------------------
cblock 0x20
aux
temp
temp2
temp3
temp4
temp5
C1 ; Columna 1 de display de matriz
C2 ; Columna 2 de display de matriz
C3 ; Columna 3 de display de matriz
C4 ; Columna 4 de display de matriz
C5 ; Columna 5 de display de matriz
C6 ; Columna 6 de display de matriz
C7 ; Columna 7 de display de matriz
C8 ; Columna 8 de display de matriz
S1 ; Posición del snake en la columna 1
S2 ; Posición del snake en la columna 2
S3 ; Posición del snake en la columna 3
S4 ; Posición del snake en la columna 4
S5 ; Posición del snake en la columna 5
S6 ; Posición del snake en la columna 6
S7 ; Posición del snake en la columna 7
S8 ; Posición del snake en la columna 8
Posind ; Indicador de columna, bits 4-0
Posdir ; Dirección del snake 0-up, 1-down, 2-left, 3-right
w_save
status_save
pclath_save
snake ; Tamaño del snake (cant de segmentos)
colind ; Indicador de colisión
rattmr ; Indica si ocurrieron las suficientes interrupciones del timer para agregar una nueva rata
T1H ; Timer1 High
endc
;-------------------------------------------------------------------------------
;----------------------------- Simbolos --------------------------------------
;-------------------------------------------------------------------------------
#define ROW1 PORTD, RD0
#define ROW2 PORTD, RD1
#define ROW3 PORTD, RD2
#define ROW4 PORTD, RD3
#define ROW5 PORTD, RD4
#define ROW6 PORTD, RD5
#define ROW7 PORTD, RD6
#define ROW8 PORTD, RD7
#define COL1 PORTC, RC0
#define COL2 PORTC, RC1
#define COL3 PORTC, RC2
#define COL4 PORTC, RC3
#define COL5 PORTC, RC4
#define COL6 PORTC, RC5
#define COL7 PORTB, RB2
#define COL8 PORTB, RB3
#define LEFT PORTB, RB5
#define RIGHT PORTB, RB4
#define DOWN PORTB, RB6
#define UP PORTB, RB7
org 0
goto Init
;-------------------------------------------------------------------------------
;----------------------------- Vector de interrupción ------------------------
;-------------------------------------------------------------------------------
org 04
goto ISR
;-------------------------------------------------------------------------------
;-------------------------- Inicializacion de Puertos ------------------------
;-------------------------------------------------------------------------------
Init
;PORTC y PORTD salidas, PORTB<RB7-RB4> entradas
banksel TRISB
movlw 0xF0
movwf TRISB
clrf TRISC
clrf TRISD
;todos los pines analogicos los hacemos digitales
banksel ANSEL
clrf ANSEL
clrf ANSELH
;comenzamos con pines de PORTB y PORTD seteados en bajo, y pines de PORTC seteados en alto
banksel PORTB
clrf PORTB
clrf PORTC
movlw 0xFF
movwf PORTD
;limpiamos los registros de variables para la lógica
clrf Posdir
clrf S1
clrf S2
clrf S3
clrf S4
clrf S5
clrf S6
clrf S7
clrf S8
clrf colind
clrf rattmr
movlw d'1'
movwf snake ; El snake empieza con un tamaño de 1 segmento
movlw d'160'
movwf FSR
clrram clrf INDF
incf FSR, f
movf FSR, w
xorlw d'230'
btfss STATUS, Z
goto clrram
;configuración de interrupciones para comunicación serie (recepción)
banksel PIE1
bsf PIE1, RCIE ;habilta interrupciones para recepción serie
bsf PIE1, TXIE ;habilta interrupciones para transmisión serie
banksel PIR1
bcf PIR1, RCIF ;comienza con el flag de recepción bajo
bcf PIR1, TXIF ;comienza con el flag de transmisión bajo
;confgiración del registro de estado y control de recepción
banksel RCSTA
bsf RCSTA, CREN ;habilita la recepción continua da datos
bsf RCSTA, SPEN ;habilita el puerto serie
banksel SPBRG
movlw .25
movwf SPBRG ;9600baud
banksel TXSTA
bsf TXSTA, BRGH ; Alta velocidad de baudrate activada
bcf TXSTA, SYNC ; modo asincrono
banksel BAUDCTL
bcf BAUDCTL, BRG16
;-------------------------------------------------------------------------------
;----------------------- Inicialización de la int del TMR0 -------------------
;-------------------------------------------------------------------------------
banksel T1CON
movlw b'00110100' ;Inicialmente inhabilitado, trabajando con clock interno, no sincronizado ,osc LP apagado , prescaler 1:8, gate inhabilitado
movwf T1CON
movlw b'00001011' ;0x0B
movwf T1H ;0xDB
movlw b'11011011'
movwf TMR1L ; genera interrupciones del timer1 cada 0.25s
banksel PIE1
bsf PIE1, TMR1IE ;Habilitación de interrupciones por TMR1
banksel PIR1
bcf PIR1, TMR1IF
bsf INTCON, GIE ;Interrupciones Globales Habilitadas
bsf INTCON, PEIE ;Habilitación por periféricos habilitada (para el TMR1)
;-------------------------------------------------------------------------------
;-------------------------------- Inicialización del Juego -------------------
;-------------------------------------------------------------------------------
;habilitamos pull-ups para RB7-RB4
banksel OPTION_REG
bcf OPTION_REG, NOT_RBPU
banksel WPUB
movlw 0xF0
movwf WPUB
;configuración de interrupción por cambio de nivel
bsf INTCON, RBIE
bcf INTCON, RBIF
banksel IOCB
movlw b'11110000'
movwf IOCB
banksel PORTA
movlw d'2' ;cargamos variable para retardo por software
call delay1 ; Demora de 0.5s
;definimos el punto donde spawnea la serpiente
movlw b'00000000'
movwf C1
movlw b'00000000'
movwf C2
movlw b'00000000'
movwf C3
movlw b'00001000' ; por defecto spawnea en la columna 4, fila 4
movwf C4
movwf S4
movlw b'00000000'
movwf C5
movlw b'00000000'
movwf C6
movlw b'00000000'
movwf C7
movlw b'00000000'
movwf C8
;indicamos que la columna de inicio es la 4
movlw b'00001000'
movwf Posind
here ;verifica si se presiona un botón, y en caso afirmativo que la direccion sea válida, si no lo es la corrige
movf Posdir, W
addlw d'0'
btfsc STATUS, Z ; Cuando se presiona un botón la serpiente comienza moverse
goto here
bsf T1CON, TMR1ON ; lanzamos la cuenta del timer
goto Start
;-------------------------------------------------------------------------------
;-------------------------------- Loops de Delays ----------------------------
;-------------------------------------------------------------------------------
delay1 movwf temp4
loopy2 movlw d'100' ;multiplos de 2.5ms
movwf temp3
loopy movlw d'250'
movwf temp
initloop goto $+1 ;2us
goto $+1 ;2us
goto $+1 ;2us
nop ;1us
decfsz temp, f ;1us
goto initloop ;2us
decfsz temp3, f
goto loopy ;250ms total
decfsz temp4, f
goto loopy2 ;multiplos de 250ms
return
;delay de 1 ms
msdelay movlw d'100'
movwf temp
loop goto $+1 ;2us
goto $+1 ;2us
goto $+1 ;2us
nop ;1us
decfsz temp, f ;1us
goto loop ;2us
return
;-------------------------------------------------------------------------------
;-------------------------------- Main-----------------------------------------
;-------------------------------------------------------------------------------
Start call Disp
btfss colind, 0
goto Start
; GAME OVER
bcf T1CON, TMR1ON ; frenar la cuenta del timer
movlw d'8'
movwf temp5
gameover movlw d'100'
movwf temp4
call Disp
decfsz temp4, f
goto $-2
movlw d'1'
call delay1 ;esperar 250ms
decfsz temp5, f
goto gameover
goto Init ;volver a empezar
;-------------------------------------------------------------------------------
;-------------------------------- Ciclo de Display ---------------------------
;-------------------------------------------------------------------------------
Disp movf C1, w
call PRTLD ;fijar estado de las filas para la columna 1
bsf COL1 ;activar columna 1
call msdelay ;esperar 1 ms
bcf COL1 ;desactivar columna 1
movf C2, w
call PRTLD ;fijar estado de las filas para la columna 2
bsf COL2 ;activar columna 2
call msdelay ;esperar 1 ms
bcf COL2 ;desactivar columna 2
movf C3, w
call PRTLD ;fijar estado de las filas para la columna 3
bsf COL3 ;activar columna 3
call msdelay ;esperar 1 ms
bcf COL3 ;desactivar columna 3
movf C4, w
call PRTLD ;fijar estado de las filas para la columna 3
bsf COL4 ;activar columna 4
call msdelay ;esperar 1 ms
bcf COL4 ;desactivar columna 4
movf C5, w
call PRTLD ;fijar estado de las filas para la columna 4
bsf COL5 ;activar columna 5
call msdelay ;esperar 1 ms
bcf COL5 ;desactivar columna 5
movf C6, w
call PRTLD ;fijar estado de las filas para la columna 5
bsf COL6 ;activar columna 6
call msdelay ;esperar 1 ms
bcf COL6 ;desactivar columna 6
movf C7, w
call PRTLD ;fijar estado de las filas para la columna 6
bsf COL7 ;activar columna 7
call msdelay ;esperar 1 ms
bcf COL7 ;desactivar columna 7
movf C8, w
call PRTLD ;fijar estado de las filas para la columna 7
bsf COL8 ;activar columna 8
call msdelay ;esperar 1 ms
bcf COL8 ;desactivar columna 8
return
PRTLD movwf temp
bsf ROW1 ;apaga todas las filas
bsf ROW2
bsf ROW3
bsf ROW4
bsf ROW5
bsf ROW6
bsf ROW7
bsf ROW8
btfsc temp, 0 ;activar fila 1?
bcf ROW1
btfsc temp, 1 ;activar fila 2?
bcf ROW2
btfsc temp, 2 ;activar fila 3?
bcf ROW3
btfsc temp, 3 ;activar fila 4?
bcf ROW4
btfsc temp, 4 ;activar fila 5?
bcf ROW5
btfsc temp, 5 ;activar fila 6?
bcf ROW6
btfsc temp, 6 ;activar fila 7?
bcf ROW7
btfsc temp, 7 ;activar fila 8?
bcf ROW8
return
;-------------------------------------------------------------------------------
;----------------------------- Programa de Interrupción -----------------------
;-------------------------------------------------------------------------------
ISR call SAVE_CX
banksel PIR1
btfsc PIR1, TMR1IF
goto TMR1_INT
btfsc PIR1, RCIF
goto RX_INT
btfsc INTCON, RBIF
goto RB_INT
goto END_ISR
RB_INT bcf INTCON, RBIF
btfss UP
goto GO_UP
btfss DOWN
goto GO_DOWN
btfss LEFT
goto GO_LEFT
btfss RIGHT
goto GO_RIGHT
goto END_ISR
GO_UP btfsc Posdir, 1 ;nos aseguramos que el snake no pueda volver sobre si mismo
goto GO_DOWN
movlw b'00000001'
movwf Posdir
goto END_ISR
GO_DOWN btfsc Posdir, 0 ;nos aseguramos que el snake no pueda volver sobre si mismo
goto GO_UP
movlw b'00000010'
movwf Posdir
goto END_ISR
GO_LEFT btfsc Posdir, 3 ;nos aseguramos que el snake no pueda volver sobre si mismo
goto GO_RIGHT
movlw b'00000100'
movwf Posdir
goto END_ISR
GO_RIGHT btfsc Posdir, 2 ;nos aseguramos que el snake no pueda volver sobre si mismo
goto GO_LEFT
movlw b'00001000'
movwf Posdir
goto END_ISR
RX_INT ; el flag se baja automaticamente luego de leer RCREG
banksel RCREG
movf RCREG, W
btfsc RCREG, 0
goto GO_LEFT; en realidad va hacia arriba en el hardware
btfsc RCREG, 1
goto GO_RIGHT
btfsc RCREG, 2
goto GO_DOWN
btfsc RCREG, 3
goto GO_UP
goto END_ISR
TMR1_INT
bcf PIR1, TMR1IF ;limpiamos flag del timer1
bcf T1CON, TMR1ON ; Detenemos el timer
movf T1H, w
movwf TMR1H
movlw b'11011011'
movwf TMR1L ; Cargamos el timer para que interrumpa cada 0,5 s
bsf T1CON, TMR1ON ; Lanzamos el timer nuevamente
btfsc rattmr, 7 ; El bit 7 inidica si hay una rata todavía no comida en el tablero
goto skip ;saltear, si ya hay una rat no se incrementa el contador de 10 interrupciones del timer1
incf rattmr, f ;si no hay rata en la tabla, incrementamos el contador de 10 interrupciones del timer1
movf rattmr, w ; y cuando llega a 10 colocamos una nueva rata en la tabla
xorlw d'10'
btfsc STATUS, Z
call Rat
skip ;averiguamos en que columna se encotnraba el head del snake al momento de la interrupción
btfsc Posind, 7 ; Columna 8?
goto Col8
btfsc Posind, 6 ; Columna 7?
goto Col7
btfsc Posind, 5 ; Columna 6?
goto Col6
btfsc Posind, 4 ; Columna 5?
goto Col5
btfsc Posind, 3 ; Columna 4?
goto Col4
btfsc Posind, 2 ; Columna 3?
goto Col3
btfsc Posind, 1 ; Columna 2?
goto Col2
; Entonces la columna 1
movf S1, w
call Checkdir
call Placecont
goto LoadDisp
Col2 movf S2, w
call Checkdir
call Placecont
goto LoadDisp
Col3 movf S3, w
call Checkdir
call Placecont
goto LoadDisp
Col4 movf S4, w
call Checkdir
call Placecont
goto LoadDisp
Col5 movf S5, w
call Checkdir
call Placecont
goto LoadDisp
Col6 movf S6, w
call Checkdir
call Placecont
goto LoadDisp
Col7 movf S7, w
call Checkdir
call Placecont
goto LoadDisp
Col8 movf S8, w
call Checkdir
call Placecont
goto LoadDisp
Placecont clrf S8
clrf S7
clrf S6
clrf S5
clrf S4
clrf S3
clrf S2
clrf S1
btfsc Posind, 7 ; Debemos cargar registro de la columna 8?
goto PlacA
btfsc Posind, 6 ; Debemos cargar registro de la columna 7?
goto PlacB
btfsc Posind, 5 ; Debemos cargar registro de la columna 6?
goto PlacC
btfsc Posind, 4 ; Debemos cargar registro de la columna 5?
goto PlacD
btfsc Posind, 3 ; Debemos cargar registro de la columna 4?
goto PlacE
btfsc Posind, 2 ; Debemos cargar registro de la columna 3?
goto PlacF
btfsc Posind, 1 ; Debemos cargar registro de la columna 2?
goto PlacG
movwf S1 ; Debemos cargar registro de la columna 1
movwf temp3
clrw
call plcdot ; El registro a cargar mapea con la columna 1, ahora averiguamos con que fila mapea
return
PlacA movwf S8
movwf temp3 ; guardamos el offset de la columna
movlw d'7' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 8, ahora averiguamos con que fila mapea
return
PlacB movwf S7
movwf temp3 ; guardamos el offset de la columna
movlw d'6' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 7, ahora averiguamos con que fila mapea
return
PlacC movwf S6
movwf temp3 ; guardamos el offset de la columna
movlw d'5' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 6, ahora averiguamos con que fila mapea
return
PlacD movwf S5
movwf temp3 ; guardamos el offset de la columna
movlw d'4' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 5, ahora averiguamos con que fila mapea
return
PlacE movwf S4
movwf temp3 ; guardamos el offset de la columna
movlw d'3' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 4, ahora averiguamos con que fila mapea
return
PlacF movwf S3
movwf temp3 ; guardamos el offset de la columna
movlw d'2' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 3, ahora averiguamos con que fila mapea
return
PlacG movwf S2
movwf temp3 ; guardamos el offset de la columna
movlw d'1' ; Indicamos la columna en la que estamos
call plcdot ; El registro a cargar mapea con la columna 2, ahora averiguamos con que fila mapea
return
Checkdir btfsc Posdir, 0 ; se desplaza hacia arriba?
goto DirectU
btfsc Posdir, 1 ; se desplaza hacia abajo?
goto DirectD
btfsc Posdir, 2 ; se desplaza a la izquierda?
goto DirectL
goto DirectR ;entonces se desplaza a la derecha
DirectU movwf temp5
rrf temp5, f ; verifiamos si la columna activa es la del extremo superior
btfsc STATUS, C
bsf temp5, 7
movf temp5, w
return
DirectD movwf temp5
rlf temp5, f ; verifiamos si la columna activa es la del extremo inferior
btfsc STATUS, C
call DirectDa
movf temp5, w
return
DirectDa clrf temp5
bsf temp5, 0
return
DirectL movwf temp5
rrf Posind, f
btfsc STATUS, C ; verifiamos si la columna activa es la del extremo izquierdo
bsf Posind, 7
movf temp5, w
return
DirectR movwf temp5
rlf Posind, f
btfsc STATUS, C ; verifiamos si la columna activa es la del extremo derecho
call DirectRa
movf temp5, w
return
DirectRa clrf Posind
bsf Posind, 0
return
LoadDisp call Decdot
movf S1, w
iorwf C1, f
movf S2, w
iorwf C2, f
movf S3, w
iorwf C3, f
movf S4, w
iorwf C4, f
movf S5, w
iorwf C5, f
movf S6, w
iorwf C6, f
movf S7, w
iorwf C7, f
movf S8, w
iorwf C8, f
goto END_ISR
SAVE_CX movwf w_save ;guardamos contexto
movf STATUS, w
clrf STATUS
movwf status_save
movf PCLATH, w
movwf pclath_save
return
END_ISR
movf pclath_save, w
movwf PCLATH
movf status_save, w
movwf STATUS
swapf w_save, f
swapf w_save, w
retfie
;-------------------------------------------------------------------------------
;---------------------------- Contador de decremento de puntos --------------- ; para el decremento de los registros cargados previamente por el head del snake
;-------------------------------------------------------------------------------
Decdot movlw d'160'
movwf temp2
clrf temp3
dotdecloop movf temp2, w
movwf FSR
movlw d'1'
subwf INDF, f
btfss STATUS, C
clrf INDF
movf INDF, w
addlw d'0'
btfsc STATUS, Z
call delum ; Apagamos el led si la ram está vacía
incf temp3, f
incf temp3, f
incf temp2, f
movf temp2, w
xorlw d'224' ;este registro es el limite de nuestra matriz
btfss STATUS, Z
goto dotdecloop
movf temp4, w ;apunto a la dirección del registro que se debe cargar
movwf FSR
movlw d'0'
addwf INDF, w ;pregunto si el registro que se debe cargar esta vacío
btfss STATUS, Z
call colrat ;si no esta
movf snake, w
movwf INDF
return
colrat btfsc INDF, 7 ; El bit 7 indica una rata
goto ratcl
bsf colind, 0
return
ratcl clrf rattmr
incf snake, f
return
delum movlw LOW table ; Apaga el led elegido
addwf temp3, w
movlw HIGH table
btfsc STATUS, C
addlw 1
movwf PCLATH
movlw LOW table
addwf temp3, w
movwf PCL
table bcf C1, 0
return
bcf C2, 0
return
bcf C3, 0
return
bcf C4, 0
return
bcf C5, 0
return
bcf C6, 0
return
bcf C7, 0
return
bcf C8, 0
return
bcf C1, 1
return
bcf C2, 1
return
bcf C3, 1
return
bcf C4, 1
return
bcf C5, 1
return
bcf C6, 1
return
bcf C7, 1
return
bcf C8, 1
return
bcf C1, 2
return
bcf C2, 2
return
bcf C3, 2
return
bcf C4, 2
return
bcf C5, 2
return
bcf C6, 2
return
bcf C7, 2
return
bcf C8, 2
return
bcf C1, 3
return
bcf C2, 3
return
bcf C3, 3
return
bcf C4, 3
return
bcf C5, 3
return
bcf C6, 3
return
bcf C7, 3
return
bcf C8, 3
return
bcf C1, 4
return
bcf C2, 4
return
bcf C3, 4
return
bcf C4, 4
return
bcf C5, 4
return
bcf C6, 4
return
bcf C7, 4
return
bcf C8, 4
return
bcf C1, 5
return
bcf C2, 5
return
bcf C3, 5
return
bcf C4, 5
return
bcf C5, 5
return
bcf C6, 5
return
bcf C7, 5
return
bcf C8, 5
return
bcf C1, 6
return
bcf C2, 6
return
bcf C3, 6
return
bcf C4, 6
return
bcf C5, 6
return
bcf C6, 6
return
bcf C7, 6
return
bcf C8, 6
return
bcf C1, 7
return
bcf C2, 7
return
bcf C3, 7
return
bcf C4, 7
return
bcf C5, 7
return
bcf C6, 7
return
bcf C7, 7
return
bcf C8, 7
return
;-------------------------------------------------------------------------------
;---------------------------- Incremento del contador de "puntos" ------------
;-------------------------------------------------------------------------------
plcdot addlw d'160' ;A0 ; El registro a cargar mapea con la fila 1
btfsc temp3, 7 ;fila 8?
addlw d'56' ;D8 ; El registro a cargar mapea con la fila 8
btfsc temp3, 6 ;fila 7?
addlw d'48' ;D0 ; El registro a cargar mapea con la fila 7
btfsc temp3, 5 ;fila 6?
addlw d'40' ;C8 ; El registro a cargar mapea con la fila 6
btfsc temp3, 4 ;fila 5?
addlw d'32' ;C8 ; El registro a cargar mapea con la fila 5
btfsc temp3, 3 ;fila 4?
addlw d'24' ;B8 ; El registro a cargar mapea con la fila 4
btfsc temp3, 2 ;fila 3?
addlw d'16' ;B0 ; El registro a cargar mapea con la fila 3
btfsc temp3, 1 ;fila 2?
addlw d'8' ;A8 ; El registro a cargar mapea con la fila 2
movwf temp4 ; temp4 contiene ahora el numero de registro que debe cargarse con el tamaño del snake
Ilum movlw d'255'
movwf C1
movwf C2
movwf C3
movwf C4
movwf C5
movwf C6
movwf C7
movwf C8
return
;-------------------------------------------------------------------------------
;--------------------------- Generación aleatorio de Rata --------------------
;-------------------------------------------------------------------------------
Rat movlw b'10000000'
movwf rattmr ;limpiamos la cuenta de 10 interrupciones del timer e indicamos que hay una rata en el tablero
call Random ; Generamos un numero "aleatorio" en base al cual elegimos en que registro colocar la rata
addlw d'159'
movwf FSR
notclr incf FSR, f
movf INDF, w
addlw d'0'
btfsc STATUS, Z
goto addrat
movf FSR, w
addlw d'33' ;aseguramos que no sea mayor a 223
btfss STATUS, C
goto notclr ; Elegimos otro registro, porque este no esta limpio
movlw d'159'
movwf FSR
goto notclr ; Location not clear, try again.
addrat movlw d'255' ; Cargamos al maximo el registro que habia quedado apuntado por el FSR, el MSB indica
movwf INDF ; si existe una colisión con una rata para el registro en cuestión
movlw d'7' ; Aumentamos la velocidad de la serpiente, (hacemos que timer1 temporize menos)
addwf T1H, f
return
;-------------------------------------------------------------------------------
;---------------------------- Generación de Número Random --------------------
;-------------------------------------------------------------------------------
Random movf snake, w ;tenemos en cuenta el tamaño del snake como varibale que influye en el numero "random" seleccionado
movwf temp3
movlw LOW Rantbl ;tomamos la parte baja de la dirección de la tabla
addwf temp3, w
movlw HIGH Rantbl ;tomamos la parte alta de la dirección de la tabla
btfsc STATUS, C
addlw 1
movwf PCLATH ;modificamos el PCLATH para modificar el PC (parte alta)
movlw LOW Rantbl
addwf temp3, w
movwf PCL ;modificamos el PCL para modificar el PC
Rantbl retlw d'2'
retlw d'49'
retlw d'7'
retlw d'62'
retlw d'11'
retlw d'42'
retlw d'50'
retlw d'37'
retlw d'54'
retlw d'47'
retlw d'3'
retlw d'59'
retlw d'61'
retlw d'21'
retlw d'6'
retlw d'40'
retlw d'19'
retlw d'34'
retlw d'10'
retlw d'8'
retlw d'41'
retlw d'58'
retlw d'18'
retlw d'46'
retlw d'53'
retlw d'26'
retlw d'51'
retlw d'25'
retlw d'33'
retlw d'1'
retlw d'45'
retlw d'9'
retlw d'0'
retlw d'57'
retlw d'35'
retlw d'32'
retlw d'52'
retlw d'17'
retlw d'4'
retlw d'22'
retlw d'43'
retlw d'55'
retlw d'5'
retlw d'12'
retlw d'60'
retlw d'16'
retlw d'20'
retlw d'30'
retlw d'39'
retlw d'63'
retlw d'24'
retlw d'31'
retlw d'56'
retlw d'36'
retlw d'48'
retlw d'13'
retlw d'27'
retlw d'15'
retlw d'23'
retlw d'38'
retlw d'44'
retlw d'28'
retlw d'14'
retlw d'29'
end