This repository has been archived by the owner on Jul 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.asm
732 lines (699 loc) · 14 KB
/
main.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
;
; Task4.asm
;
; Created: 18-02-22 14:34:12
; Author : Oscar
;
.INCLUDE "m328pdef.inc"
.ORG 0x0000
RJMP init ;Start execution at init
.ORG 0x0012
RJMP Buzzer ;Timer 2: Buzzer
.ORG 0x001a
RJMP updateGame ;Timer 1: Game update
.ORG 0x0020
RJMP updateDisplay ;Timer 0: Display update
init:
BSET 7 ;Enable Interrupt Globally
;Timer 0 for the screen
LDI R17,0x04 ;Prescale 256
LDI R19,0x30 ;Initial value at 48 -> 150Hz in real world
OUT TCCR0B,R17
OUT TCNT0,R19
;Timer 1 for game update
LDI R17,0x04 ;Prescale 256
LDI R25,0xc0 ;Overflow High
LDI R24,0xf0 ;Overflow Low
STS TCCR1B,R17
STS TCNT1H,R25
STS TCNT1L,R24 ;Real world frequency: ~3Hz
;Timer 2 for buzzer
LDI R17,0x04 ;Prescale 64
LDI R19,0xB9 ;Initial value at 185
STS TCCR2B,R17
STS TCNT2,R19
;BUZZER
SBI DDRB,1
SBI PORTB,1
;Leds
SBI DDRC,2
SBI PORTC,2
SBI DDRC,3
SBI PORTC,3
;Keyboard
LDI R16,0x0F
OUT DDRD,R16
LDI R16,0xFF
OUT PORTD,R16
;SCREEN
SBI DDRB,5
SBI PORTB,5
SBI DDRB,3
SBI PORTB,3
SBI DDRB,4
SBI PORTB,4
;Inital value for layer width
LDI R21, 0x04
gameSetup:
SBI PORTC,2 ;Clear gameover led
;Erase Screenbuffer and prebuffer
LDI R17,0x00
LDI ZL,0x00
LDI ZH,0x01
LDI R16,94 ;Counter to 80+14 bytes for ScreenBuffer + PreBuffer
WriteClearBuffer:
ST Z+,R17
DEC R16
BRNE WriteClearBuffer
;Create player at center of playerbuffer
LDI ZL,0x5e
LDI ZH,0x01
LDI R16,6
WriteClearPlayer1:
ST Z+,R17
DEC R16
BRNE WriteClearPlayer1
LDI R18,0b00001100
ST Z+,R18
ST Z+,R18
LDI R16,6
WriteCleanPlayer2:
ST Z+,R17
DEC R16
BRNE WriteCleanPlayer2
;Set the Level Table pointer
LDI ZL, low(LevelTable<<1)
LDI ZH, high(LevelTable<<1)
;Set the layer width counter
MOV R23,R21
;Clear the buzzer duration counter
LDI R22,0x00
;Enable interrupt for timer 0 (screen) and 1 (game) but not timer 2 (buzzer)
LDI R18,0x01
STS TIMSK0,R18
STS TIMSK1,R18
LDI R18,0x00
STS TIMSK2,R18
main:
;Check if setting button is pressed
LDI R16,0xff
;First row
OUT PORTD,R16
CBI PORTD,3
NOP
NOP
NOP
NOP
SBIS PIND,7
RJMP gameSetup
SBIS PIND,5
RJMP increaseSpeed
SBIS PIND,4
RJMP decreaseSpeed
;Second row
OUT PORTD,R16
CBI PORTD,2
NOP
NOP
NOP
NOP
SBIS PIND,5
RJMP increaseWidth
SBIS PIND,4
RJMP decreaseWidth
;Check is the game is not over
LDS R17,TIMSK1
CPI R17,0
SBRS R17,0
RJMP nothing
;Check if controlle button is pressed
;Third row
OUT PORTD,R16
CBI PORTD,1
NOP
NOP
NOP
SBIS PIND,5
RJMP moveTop
;Fourth row
OUT PORTD,R16
CBI PORTD,0
NOP
NOP
NOP
SBIS PIND,6
RJMP moveRight
SBIS PIND,5
RJMP moveBottom
SBIS PIND,4
RJMP moveLeft
nothing:
;If nothing pressed, clear LED 3
SBI PORTC,3
RJMP main
;Buttons Action
increaseSpeed:
SBIS PINC,3
RJMP main
LDI R16,0x08
ADD R25,R16
CPI R25,0xf0
BRLO nocarryinc
LDI R25,0xf0
RJMP main
nocarryinc:
CBI PORTC,3
RJMP main
decreaseSpeed:
SBIS PINC,3
RJMP main
SUBI R25,8
CPI R25,0x10
BRSH nocarrydec
LDI R25,0x10
RJMP main
nocarrydec:
CBI PORTC,3
RJMP main
increaseWidth:
SBIS PINC,3
RJMP main
INC R21
CPI R21,16
BRLO nooverinc
LDI R21,16
RJMP main
nooverinc:
CBI PORTC,3
RJMP main
decreaseWidth:
SBIS PINC,3
RJMP main
DEC R21
CPI R21,1
BRSH nonegdec
LDI R21,0x01
RJMP main
nonegdec:
CBI PORTC,3
RJMP main
moveLeft:
SBIS PINC,3
RJMP main
CBI PORTC,3
LDI XL,0x6c
LDI XH,0x01
LD R17,-X
LDI XL,0x5e
LDI XH,0x01
LDI R16,14
loopMoveRight:
LD R18,X
ST X+,R17
MOV R17,R18
DEC R16
BRNE loopMoveRight
RJMP main;
moveRight:
SBIS PINC,3
RJMP main
CBI PORTC,3
LDI XL,0x5e
LDI XH,0x01
LD R17,X
LDI XL,0x6c
LDI XH,0x01
LDI R16,14
loopMoveLeft:
LD R18,-X
ST X,R17
MOV R17,R18
DEC R16
BRNE loopMoveLeft
RJMP main
moveBottom:
SBIS PINC,3
RJMP main
CBI PORTC,3
LDI XL,0x5e
LDI XH,0x01
LDI R16,14
LDI R18,0
loopCheckBottom:
CLC
LD R17,X+
ROL R17
BRCC carryClearBottom
INC R18
carryClearBottom:
DEC R16
BRNE loopCheckBottom
TST R18
BREQ rolBottom
RJMP main
rolBottom:
LDI R16,14
loopMoveBottom:
CLC
LD R17,-X
ROL R17
ST X,R17
DEC R16
BRNE loopMoveBottom
RJMP main
moveTop:
SBIS PINC,3
RJMP main
CBI PORTC,3
LDI XL,0x5e
LDI XH,0x01
LDI R16,14
LDI R18,0
loopCheckTop:
CLC
LD R17,X+
ROR R17
BRCC carryClearTop
INC R18
carryClearTop:
DEC R16
BRNE loopCheckTop
TST R18
BREQ rolTop
RJMP main
rolTop:
LDI R16,14
loopMoveTop:
CLC
LD R17,-X
ROR R17
ST X,R17
DEC R16
BRNE loopMoveTop
RJMP main
;TIMER 1
updateGame:
;Clear interrupt
SBI TIFR1,TOV1
STS TCNT1H,R25
STS TCNT1L,R24
;Store registers and SREG taht will be used locally
PUSH R16
PUSH R17
PUSH R18
PUSH R19
PUSH R26
PUSH R27
PUSH R28
PUSH R29
IN R16,SREG
PUSH R16
;Check if a new layer should be load from Level Table to Prebuffer (depending on the layer width)
DEC R23
BRNE ShiftBuffer
LDI XL,0x50
LDI XH,0x01
LDI R16,2
LoadLayerLoop:
LPM R17,Z+
LDI R18,7 ;Counter to only read the 7 MSB bit
writePreBufferBytes:
ROL R17
BRCC ZerosBytes
LDI R19,0xff
RJMP WriteToPreBuffer
ZerosBytes:
LDI R19,0x00
WriteToPreBuffer:
ST X+,R19
DEC R18
BRNE writePreBufferBytes
DEC R16
BRNE LoadLayerLoop
MOV R23,R21
shiftBuffer:
;Shift the game content and copy the prebuffer to the first row of the screenbuffer
LDI XL,0x00 ;ScreenBufferPointer
LDI XH,0x01
LDI YL,0x50 ;PreBufferPointer
LDI YH,0x01
LDI R16,14 ;Counter for each column
columnLoopShift:
LD R18,Y+
CLC
ROR R18
LDI R17,5 ;Row counter
rowLoopShift:
LD R18,X
ROL R18
ST X+,R18
DEC R17
BRNE rowLoopShift
DEC R16
BRNE columnLoopShift
;Retrieve stored register and SREG
POP R16
OUT SREG,R16
POP R29
POP R28
POP R27
POP R26
POP R19
POP R18
POP R17
POP R16
reti
;TIMER
updateDisplay:
;Store registers and SREG that will be used locally
PUSH R16
PUSH R17
PUSH R18
PUSH R19
PUSH R20
PUSH R21
PUSH R26
PUSH R27
IN R16,SREG
PUSH R16
;Clear interrupt
SBI TIFR0,TOV0 ;Clear interrupt flag
LDI R16,0x30 ;Initial value at 220 -> 880Hz
OUT TCNT0,R16
;Update the display
LDI XL,0x4B ;ScreenBuffer pointer
LDI XH,0x01
LDI YL,0x6d ;Player pointer
LDI YH,0x01
LDI R21,0 ;Game state (00 = running, ff = game over)
LDI R16,0x01 ;Shifting bytes for the active colum
displayLoop:
LDI R17,5 ;Counter for the column (end after 5 iteration)
columnLoop1:
LDI R18,0x08 ;Counter for the 8 bits shifting
LD R19,-X ;Load the 8 bits from the pointer address
CPI R17,5
BRNE wordLoop1
LD R20,-Y
AND R20,R19
BREQ noCollision1
LDI R21,0xff ;Game over
noCollision1:
LD R20,Y
OR R19,R20
wordLoop1:
CBI PORTB,3
ROL R19
BRCC CarryIs01
SBI PORTB,3
CarryIs01:
CBI PORTB,5 ;Rising egde of PB5 to shift the register
SBI PORTB,5
DEC R18 ;Dec the counter of the 8 shifts
BRNE wordLoop1
DEC R17
BRNE columnLoop1
SBIW XH:XL,30 ;Offset to match the electronic layout (see report)
SBIW YH:YL,6
LDI R17,5
columnLoop2:
LDI R18,0x08 ;counter for the 8 bits shifting
LD R19,-X ;Load the 8 bits from the pointer address
CPI R17,5
BRNE wordLoop2
LD R20,-Y
AND R20,R19
BREQ noCollision2
LDI R21,0xff ;Game over
noCollision2:
LD R20,Y
OR R19,R20
wordLoop2:
CBI PORTB,3
ROL R19
BRCC CarryIs02
SBI PORTB,3
CarryIs02:
CBI PORTB,5 ;Rising egde of PB5 to shift the register
SBI PORTB,5
DEC R18 ;Dec the counter of the 8 shifts
BRNE wordLoop2
DEC R17
BRNE columnLoop2
ADIW XH:XL,35
ADIW YH:YL,7
LDI R17,0x8 ;counter for the row
CLC
rowLoop:
CBI PORTB,3
ROR R16
BRCC CarryIsNull
SBI PORTB,3
CarryIsNull:
CBI PORTB,5
SBI PORTB,5
DEC R17
BRNE rowLoop
SBI PORTB,4
LDI R17,255
delay:
NOP
NOP
NOP
DEC R17
BRNE delay
CBI PORTB,4
TST R16
BREQ endUpdateDisplay
RJMP displayLoop
endUpdateDisplay:
CPI R21,0
BREQ endDisplay
;IF game is over
stoppedGame:
;Turn led 2 and buzzer on the first time the game is over (if led 2 is clear before)
SBIC PINC,2
LDI R22,0xFF
LDI R21,1 ;Start buzzer
STS TIMSK2,R21
CBI PORTC,2 ;Turn LED2 Off
LDI R21,0
STS TIMSK1,R21 ;Stop game update
;Turn buzzer of when the duration register is 0
CPI R22,0
BRNE endDisplay
LDI R21,0
STS TIMSK2,R21
endDisplay:
POP R16
OUT SREG,R16
POP R27
POP R26
POP R21
POP R20
POP R19
POP R18
POP R17
POP R16
reti
;Timer 2
Buzzer:
PUSH R16
PUSH R17
SBI TIFR2,TOV2 ;Clear the overflow bit (by setting it, yeah it's stupid)
SBI PINB,1 ;Inverse the pin of the buzzer
LDI R16,0xB9 ;Initial value at 185
STS TCNT2,R16
DEC R22
POP R17
POP R16
reti
LevelTable:
;db 0bxxxxxxx0,0bxxxxxxx0
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11100000,0b00011110
.db 0b11000000,0b00001110
.db 0b10000000,0b00000110
.db 0b10000010,0b10000010
.db 0b10000010,0b10000010
.db 0b11000000,0b11000000
.db 0b10000010,0b10000010
.db 0b00000110,0b00000110
.db 0b10000010,0b10000010
.db 0b10000000,0b00000110
.db 0b11000000,0b00001110
.db 0b11100000,0b00011110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11100000,0b00011110
.db 0b11000000,0b00001110
.db 0b10000000,0b00000110
.db 0b10000010,0b10000010
.db 0b10000010,0b10000010
.db 0b11000000,0b11000000
.db 0b10000010,0b10000010
.db 0b00000110,0b00000110
.db 0b10000010,0b10000010
.db 0b10000000,0b00000110
.db 0b11000000,0b00001110
.db 0b11100000,0b00011110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00111110
.db 0b11111000,0b00011110
.db 0b11111100,0b00001110
.db 0b11111110,0b00000110
.db 0b11111110,0b00000110
.db 0b11111100,0b00001110
.db 0b11111000,0b00011110
.db 0b11110000,0b00111110
.db 0b11100000,0b01111110
.db 0b11000000,0b11111110
.db 0b10000010,0b11111110
.db 0b00000110,0b11111110
.db 0b00000110,0b11111110
.db 0b10000010,0b11111110
.db 0b11000000,0b11111110
.db 0b11100000,0b01111110
.db 0b11110000,0b00111110
.db 0b11110000,0b00011110
.db 0b11100000,0b00001110
.db 0b11000000,0b00000110
.db 0b10000000,0b00000010
.db 0x00,0x00
.db 0x00,0x00
.db 0b00111000,0b00111000 ;GG
.db 0b01000100,0b01000100
.db 0b01100100,0b01100100
.db 0b00000100,0b00000100
.db 0b00111000,0b00111000
.db 0x00,0x00
.db 0x00,0x00
.db 0xff,0xff
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00
.db 0x00,0x00