-
Notifications
You must be signed in to change notification settings - Fork 1
/
tetris.asm
2167 lines (1844 loc) · 60.2 KB
/
tetris.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
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; *************************************************************************
; * Attempt at a copy-cat game like Tetris
; * Author Daniel Tremblay
; * Code written for the C256 Foenix retro computer
; * Permission is granted to reuse this code to create your own games
; * for the C256 Foenix.
; * Copyright Daniel Tremblay 2020
; * This code is provided without warranty.
; * Please attribute credits to Daniel Tremblay if you reuse.
; *************************************************************************
.cpu "65816"
.include "macros_inc.asm"
.include "bank_00_inc.asm"
.include "timer_def.asm"
.include "vicky_ii_def.asm"
.include "interrupt_def.asm"
.include "io_def.asm"
.include "kernel_inc.asm"
.include "math_def.asm"
.include "GABE_Control_Registers_def.asm"
.include "base.asm"
.include "EXP_C200_EVID_def.asm"
* = $000500
.include "keyboard_def.asm"
* = $160000
.include "interrupt_handler.asm"
TARGET_FMX = 1
TARGET_U = 2
COLUMNS_PER_LINE = 80
TICK_COUNT .byte 0
BOARDX .byte 0
BOARDY .byte 0
CURRENT_PIECE .byte 0
NEXT_PIECE .byte 0
PIECE_X .word 5
PIECE_Y .word 0
PIECE_ROT .byte 0
PIECE_FIT .byte 0
GAME_SPEED .byte 0 ; how many ticks beteen bars falling
PIECE_CNTR .byte 0 ; we increase the speed of the game for every 10 pieces
SCORE .fill 4, 0 ; decimal formatted score
GAME_STATE .byte 4
GS_RUNNING = 0 ; 0 - running,
GS_GAME_OVER = 1 ; 1 - game over,
GS_RESTARTING = 2 ; 2 - restarting,
GS_LINE_BONUS = 3 ; 3 - display line bonus,
GS_INTRO = 4 ; 4 - intro display
GS_NAME_ENTRY = 5 ; 5 - name entry
LEVEL .byte 1
INITIAL_GAME_SPEED = 40
BOARD_WIDTH = 14
BOARD_HEIGHT = 21
START_BOARD = (1 + $40 * 5 + (40-BOARD_WIDTH)/2) * 2 + <>TL_MAP_0_ADDR
NEXT_PIECE_LOC = (1 + $40 *11 + 31) * 2 + <>TL_MAP_0_ADDR
PIECE_VALUE = $25 ; we're doing BCD additions
EFFECT_T_POSITION = $60 ; 4 bytes
EFFECT_T_WAIT_CNTR= $64 ; 2 bytes
EFFECT_L_POSITION = $66 ; 4 bytes
EFFECT_L_WAIT_CNTR= $6a ; 2 bytes
EFFECT_R_POSITION = $6c ; 4 bytes
MSG_ADDR = $70
DEL_LINE_PTR = $70
ROT_VAL = $72
ROT_VAL2 = $73
LINE_CNTR = $74
COPY_LINE_PTR = $76
TOTAL_LINES = $78 ; reserving 2 bytes
EFFECT_PLAY = $7A ; 1 byte - 0 nothing, 1 tile down, 2 line, 4 rotate.
TILE_EFFECT = $1
LINE_EFFECT = $2
ROTATE_EFFECT = $4
EFFECT_R_WAIT_CNTR= $7B ; 2 bytes
BUTTON_PRESS = $7D ; 1 byte
HISCORE_LINE = $7E ; 1 byte
; $7F is used by the VGM player - leave it alone
GAME_OVER_TIMER = $80 ; 1 byte
GAME_OVER_TICK = $81 ; 1 byte
INTRO_SLIDE_CNT = $82 ; 1 byte
JOYSTICK_POLL = $83 ; 1 byte
OPM_BASE_ADDRESS = $AFF000
PSG_BASE_ADDRESS = $AFF100
OPN2_BASE_ADDRESS = $AFF200
OPL3_BASE_ADRESS = $AFE600
; VGM Registers
SONG_START = $84 ; 4 bytes
CURRENT_POSITION = $88 ; 4 bytes
WAIT_CNTR = $8C ; 2 bytes
LOOP_OFFSET_REG = $8E ; 2 bytes
; TEMPORARY MEMORY LOCATION
TEMP_LOCATION = $90 ; 2 bytes
HISCORE_OFFSET = $92 ; 1 byte
TILESET_ADDR = $B00000
TL_MAP_0_ADDR = $B01000
TL_MAP_1_ADDR = $B01800
BACKGROUND_ADDR = $B10000
GAME_START
setas
setxl
LDA #0
STA KEYBOARD_SC_FLG
STA MOUSE_PTR_CTRL_REG_L ; disable the mouse pointer
STA VKY_TXT_CURSOR_CTRL_REG ; disable the cursor
STA EFFECT_PLAY
STA HISCORE_OFFSET
; set border color to 0
STA BORDER_COLOR_B
STA BORDER_COLOR_G
STA BORDER_COLOR_R
LDA #1
STA LEVEL
STA BORDER_CTRL_REG ; enable the border
LDA #$20
STA BORDER_X_SIZE
STA BORDER_Y_SIZE
.for sc := 0, sc < 64, sc += 1
LDA #' '
STA EVID_TEXT_MEM + 100 * sc
LDA #$10
STA EVID_COLOR_MEM + 100 * sc
.next
setal
LDA #5
STA GABE_RNG_SEED_LO ; set the max value from 0 to 6
STA PIECE_X
setas
LDA #EVID_Ctrl_Text_Mode_En
STA EVID_MSTR_CTRL_REG_L
LDA #'A'
STA EVID_TEXT_MEM + 100 * 2
LDA #$10
STA EVID_COLOR_MEM + 100 * 2
JSR LOAD_GAME_ASSETS
JSR ISDOS_INIT
JSR LOAD_HI_SCORES
LDA #GS_INTRO
;LDA #GS_NAME_ENTRY ; test hiscore
STA GAME_STATE
JSR CLEAR_TILESET
JSR VGM_INIT_TIMERS
; set the display mode to tiles
LDA #Mstr_Ctrl_TileMap_En + Mstr_Ctrl_Bitmap_En + Mstr_Ctrl_Text_Mode_En + Mstr_Ctrl_Graph_Mode_En + Mstr_Ctrl_Text_Overlay
STA MASTER_CTRL_REG_L
; enable Random Number Generation
LDA #1
STA GABE_RNG_CTRL
NEXT_GAME
JSL CLRSCREEN ; clears the text
; Enable SOF and TIMER0
LDA #~( FNX0_INT00_SOF | FNX0_INT02_TMR0 | FNX0_INT03_TMR1)
STA @lINT_MASK_REG0
; Enable Keyboard
LDA #~( FNX1_INT00_KBD )
STA @lINT_MASK_REG1
LDA GAME_STATE
CMP #GS_INTRO
BNE SKIP_INTRO
JSR DISPLAY_INTRO
CLI
BRA INFINITE_LOOP
SKIP_INTRO
SEI
RANDOM_TRY_AGAIN
LDA GABE_RNG_DAT_LO
AND #7
STA NEXT_PIECE
CMP #7
BEQ RANDOM_TRY_AGAIN
JSR PICK_NEXT_PIECE
JSR DRAW_NEXT_PIECE
CLI
; wait for interrupts
INFINITE_LOOP
NOP
NOP
NOP
LDA GAME_STATE
CMP #GS_RESTARTING
BNE IL_DONE
LDA #GS_RUNNING
STA GAME_STATE
JSR INIT_GAME
BRA NEXT_GAME
IL_DONE
BRA INFINITE_LOOP
DISPLAY_BOARD_LOOP
.as
; TIMING
LDA TICK_COUNT
INC A
STA TICK_COUNT
CMP GAME_SPEED
BNE TIMING_DONE
LDA PIECE_Y
INC A
STA PIECE_Y
LDA #0
STA TICK_COUNT
TIMING_DONE
; does the piece fit in this position?
JSR DOES_PIECE_FIT
LDA PIECE_FIT
BEQ LOGIC_DONE
; if Y position is 0, then game over
LDA PIECE_Y
BNE NOT_GAME_OVER
JMP GAME_OVER
NOT_GAME_OVER
; set the piece in place
JSR PLAY_EFFECT_TILE_DOWN
JSR COPY_PIECE
setal
SED
CLC
LDA SCORE
ADC #PIECE_VALUE
STA SCORE
BCC NG_CONTINUE ; carry
; increment the hi-byte
CLC
LDA SCORE+2
ADC #1
STA SCORE+2
NG_CONTINUE
CLD
setas
JSR LOOK_FOR_LINES
; choose another piece and set it at the top
LDA #5
STA PIECE_X
LDA #0
STA PIECE_Y
STA PIECE_FIT
STA PIECE_ROT
STA TICK_COUNT
JSR PICK_NEXT_PIECE
; draw the next piece
JSR DRAW_NEXT_PIECE
LDA PIECE_CNTR
INC A
STA PIECE_CNTR
CMP #10
BNE LOGIC_DONE
; increase difficulty level and game speed
LDA #0
STA PIECE_CNTR
SED
CLC
LDA LEVEL
ADC #1
STA LEVEL
CLD
LDA GAME_SPEED
SEC
SBC #2
STA GAME_SPEED
LOGIC_DONE
JSR DRAW_BOARD
JSR DRAW_PIECE
JSR DRAW_HI_SCORES
JSR DRAW_SCORE
JSR DRAW_LEVEL
JSR DRAW_LINES
RTS
PICK_NEXT_PIECE
.as
LDA NEXT_PIECE
STA CURRENT_PIECE
PN_TRY_AGAIN
LDA GABE_RNG_DAT_LO
AND #7
STA NEXT_PIECE
CMP #7
BEQ PN_TRY_AGAIN
RTS
DISPLAY_SYMBOL
.as
STA [CURSORPOS]
setal
LDA CURSORPOS
CLC
ADC #$2000
STA COLORPOS
setas
LDA CURCOLOR
STA [COLORPOS]
RTS
INVALID_KEY
RTS
; *******************************************************************
; * Look for lines
; *******************************************************************
LOOK_FOR_LINES
.as
STZ ROT_VAL2 ; line count max 4
STZ LINE_CNTR
STZ LINE_CNTR + 1
INIT_LINE_CHECK
LDY #0
STZ ROT_VAL ; column count max 10
setal
LDA PIECE_Y
DEC A
STA UNSIGNED_MULT_A
LDA #BOARD_WIDTH
STA UNSIGNED_MULT_B
LDA UNSIGNED_MULT_RESULT
TAX
setas
CHK_NEXT_COL
LDA BOARD,X
BEQ CHK_NEXT_LINE
INC ROT_VAL
INX
INY
CPY #BOARD_WIDTH
BNE CHK_NEXT_COL
LDA ROT_VAL
CMP #BOARD_WIDTH
BEQ LINE_FOUND
CHK_NEXT_LINE
INC ROT_VAL2
LDA PIECE_Y
INC A
STA PIECE_Y
CMP #BOARD_HEIGHT
BEQ LOOK_LINE_DONE
LDA ROT_VAL2
CMP #4
BNE INIT_LINE_CHECK
LOOK_LINE_DONE
RTS
LINE_FOUND
INC LINE_CNTR
LDA #3
STA GAME_STATE
setal
LDA PIECE_Y
DEC A
STA UNSIGNED_MULT_A
LDA #BOARD_WIDTH
STA UNSIGNED_MULT_B
LDA UNSIGNED_MULT_RESULT
TAX
setas
INX
INX ; skip the first two columns
LDY #0
LDA #9
STA BOARD,X
INX
INY
LDA #10
LINE_CHAR
STA BOARD,X
INX
INY
CPY #BOARD_WIDTH-5
BNE LINE_CHAR
LDA #11
STA BOARD,X
BRA CHK_NEXT_LINE
GET_PIECE_VALUE
.as
LDA #0
XBA
LDA PIECE_ROT
BNE ROT_NEXT
LDA PIECE0,X ; ROTATION 0
RTS
ROT_NEXT
CMP #1
BNE ROT_2
PHX
TXA
AND #$F0
STA ROT_VAL2
TXA
AND #3
TAX
SEC
LDA #12 ; ROTATION 1
CMP_R1
CPX #0
BEQ R1_DONE
SBC #4
DEX
BRA CMP_R1
R1_DONE
STA ROT_VAL
LDA 1,S
LSR A
LSR A
AND #3
CLC
ADC ROT_VAL
ADC ROT_VAL2
TAX
LDA PIECE0,X ; ROTATION 1
PLX
RTS
ROT_2
CMP #2
BNE ROT_3
PHX
TXA
AND #$F0
STA ROT_VAL2
TXA
AND #$F
STA ROT_VAL
SEC
LDA #$F
SBC ROT_VAL
CLC
ADC ROT_VAL2
TAX
LDA PIECE0,X ; ROTATION 2
PLX
RTS
ROT_3
PHX
TXA
AND #$F0
STA ROT_VAL2
TXA
AND #$C
LSR A
LSR A
STA ROT_VAL
LDA 1,S
AND #3
TAX
LDA #3 ; ROTATION 3
CMP_R3
CPX #0
BEQ R3_DONE
CLC
ADC #4
DEX
BRA CMP_R3
R3_DONE
SEC
SBC ROT_VAL
CLC
ADC ROT_VAL2
TAX
LDA PIECE0,X ; ROTATION 3
PLX
RTS
; *****************************************************************************
; * Handle Joystick Movements
; * Remember that the joystick at rest returns $9F.
; * Poll the joystick 10 times a second.
; *****************************************************************************
HANDLE_JOYSTICK
.as
LDA JOYSTICK_POLL
INC A
STA JOYSTICK_POLL
CMP #6
BNE JS_DONE
STZ JOYSTICK_POLL
LDA JOYSTICK0
; we don't care about up #1
BIT #2 ; down
BNE JS_LEFT
STZ BUTTON_PRESS
JSR MOVE_PIECE_DOWN
BRA JS_DONE
JS_LEFT
BIT #4 ; left
BNE JS_RIGHT
STZ BUTTON_PRESS
JSR MOVE_PIECE_LEFT
BRA JS_DONE
JS_RIGHT
BIT #8 ; right
BNE JS_BUTTON
STZ BUTTON_PRESS
JSR MOVE_PIECE_RIGHT
BRA JS_DONE
JS_BUTTON
BIT #$10 ; button
BNE JS_NONE
LDA BUTTON_PRESS
BNE JS_DONE
LDA #1
STA BUTTON_PRESS
JSR ROTATE_PIECE
RTS
JS_NONE
STZ BUTTON_PRESS
JS_DONE
RTS
; *****************************************************************************
; * User Pressed Left Arrow
; *****************************************************************************
MOVE_PIECE_LEFT
.as
LDA GAME_STATE
CMP #1 ; user pressed the space bar to restart the game
BEQ MOVE_LEFT_DONE
LDA PIECE_X
DEC A
STA PIECE_X
JSR DOES_PIECE_FIT
LDA PIECE_FIT
BEQ MOVE_LEFT_DONE
; collision detected
LDA PIECE_X
INC A
STA PIECE_X
LDA #0
STA PIECE_FIT
MOVE_LEFT_DONE
RTS
; *****************************************************************************
; * User Pressed Right Arrow
; *****************************************************************************
MOVE_PIECE_RIGHT
.as
LDA GAME_STATE
CMP #1 ; user pressed the space bar to restart the game
BEQ MOVE_RIGHT_DONE
LDA PIECE_X
INC A
STA PIECE_X
JSR DOES_PIECE_FIT
LDA PIECE_FIT
BEQ MOVE_RIGHT_DONE
; collision detected
LDA PIECE_X
DEC A
STA PIECE_X
LDA #0
STA PIECE_FIT
MOVE_RIGHT_DONE
RTS
; *****************************************************************************
; * User Pressed Down Arrow
; *****************************************************************************
MOVE_PIECE_DOWN
.as
LDA GAME_STATE
CMP #1 ; user pressed the space bar to restart the game
BEQ MOVE_DOWN_DONE
LDA PIECE_Y
INC A
STA PIECE_Y
JSR DOES_PIECE_FIT
LDA PIECE_FIT
BEQ MOVE_DOWN_DONE
LDA PIECE_Y
DEC A
STA PIECE_Y
LDA #0
STA PIECE_FIT
MOVE_DOWN_DONE
RTS
; *****************************************************************************
; * User Pressed Space Bar
; *****************************************************************************
ROTATE_PIECE
.as
LDA GAME_STATE
CMP #GS_GAME_OVER ; user pressed the space bar to restart the game
BEQ CHANGE_STATE
CMP #GS_INTRO
BNE ROT_START
CHANGE_STATE
LDA #GS_RESTARTING
STA GAME_STATE
RTS
ROT_START
LDA PIECE_ROT
INC A
CMP #4
BNE ROTATE_CHECK_COLLISION
LDA #0
ROTATE_CHECK_COLLISION
STA PIECE_ROT
JSR DOES_PIECE_FIT
LDA PIECE_FIT
BEQ ROTATE_DONE
LDA #0
STA PIECE_FIT
; collision detected
LDA PIECE_ROT
BEQ ROTATE_3
DEC A
BRA UNDO_ROT_COLISION
ROTATE_3
LDA #3
UNDO_ROT_COLISION
STA PIECE_ROT
RTS
ROTATE_DONE
JSR PLAY_EFFECT_ROTATE
RTS
; *****************************************************************************
; * Lock a piece into place
; *****************************************************************************
COPY_PIECE
.as
LDA CURRENT_PIECE
ASL A
ASL A
ASL A
ASL A
TAX
setal
LDA PIECE_Y
DEC A
STA UNSIGNED_MULT_A
LDA #BOARD_WIDTH
STA UNSIGNED_MULT_B
LDA UNSIGNED_MULT_RESULT
CLC
ADC PIECE_X
TAY
LDA #0
setas
NEXT_COPY
JSR GET_PIECE_VALUE
CMP #0
BEQ SKIP_COPY
; is the board occupied for this byte
PHX
TYX
CLC
LDA CURRENT_PIECE
ADC #2
STA BOARD,X
PLX
SKIP_COPY
INX
INY
TXA
AND #3
BNE NEXT_COPY
setal
TYA
CLC
ADC #BOARD_WIDTH-4
TAY
setas
TXA
AND #$F
BNE NEXT_COPY
RTS
; *****************************************************************************
; * This is the tougher function. Used to detect collisions.
; *****************************************************************************
DOES_PIECE_FIT
.as
LDA #0
XBA
LDA CURRENT_PIECE
ASL A
ASL A
ASL A
ASL A
TAX
setal
LDA PIECE_Y
STA UNSIGNED_MULT_A
LDA #BOARD_WIDTH
STA UNSIGNED_MULT_B
LDA UNSIGNED_MULT_RESULT
CLC
ADC PIECE_X
TAY
LDA #0
setas
NEXT_COLLISION
JSR GET_PIECE_VALUE
CMP #0
BEQ SKIP_BYTE
; is the board occupied for this byte
PHX
TYX
LDA BOARD,X
PLX
CMP #0
BNE OCCUPIED
SKIP_BYTE
INX
INY
TXA
AND #3
BNE NEXT_COLLISION
setal
TYA
CLC
ADC #BOARD_WIDTH-4
TAY
setas
TXA
AND #$F
BNE NEXT_COLLISION
BRA PF_DONE
; passed the end of the board
OCCUPIED
LDA #1
STA PIECE_FIT
PF_DONE
RTS
; draw the board as tiles
DRAW_BOARD
.as
.xl
LDX #START_BOARD
STX CURSORPOS
LDA #`TL_MAP_0_ADDR
STA CURSORPOS + 2
LDX #0
LDA #0
STA BOARDY
NEXT_ROW
LDA #0
STA BOARDX
NEXT_SYMBOL
LDA BOARD,X
CMP #'#'
BNE SKIP_DR_BRD
LDA #1
BRA DISPLAY_BLOCK
SKIP_DR_BRD
;LDA #0
DISPLAY_BLOCK
STA [CURSORPOS]
INX
INC CURSORPOS
; each tile is 16 bits - the second byte is tileset0 and lut0
LDA #0
STA [CURSORPOS]
INC CURSORPOS
LDA BOARDX
INC A
STA BOARDX
CMP #BOARD_WIDTH
BNE NEXT_SYMBOL
setal
LDA CURSORPOS
CLC
ADC #($40-BOARD_WIDTH) * 2
STA CURSORPOS
setas
LDA BOARDY
INC A
STA BOARDY
CMP #BOARD_HEIGHT
BNE NEXT_ROW
RTS
DRAW_PIECE
.as
LDA #`TL_MAP_0_ADDR
STA CURSORPOS + 2
setal
LDA #START_BOARD
CLC
ADC PIECE_X
ADC PIECE_X ; multiply by 2
STA CURSORPOS
LDA #128 ; each tile is 16-bits
STA UNSIGNED_MULT_A
LDA PIECE_Y
STA UNSIGNED_MULT_B
LDA UNSIGNED_MULT_RESULT
CLC
ADC CURSORPOS
STA CURSORPOS
setas
LDA #0
XBA
LDA CURRENT_PIECE ; each piece is 16 bytes
ASL A
ASL A
ASL A
ASL A
TAX
DP_NEXT_PIECE_SYMBOL
JSR GET_PIECE_VALUE
CMP #0
BEQ SKIP_DRAW
LDA CURRENT_PIECE ; skip first two tiles
CLC
ADC #2
STA [CURSORPOS]
SKIP_DRAW
INX
INC CURSORPOS
LDA #0
STA [CURSORPOS]
INC CURSORPOS
TXA
AND #3
BNE DP_NEXT_PIECE_SYMBOL
setal
LDA CURSORPOS
CLC
ADC #($40-4) * 2
STA CURSORPOS
TXA
AND #$F
setas
BNE DP_NEXT_PIECE_SYMBOL
RTS
DRAW_NEXT_PIECE
.as
LDY #$A000 + COLUMNS_PER_LINE * 16 + 56
STY CURSORPOS
LDA #$AF
STA CURSORPOS + 2
LDA #$20
STA CURCOLOR
LDY #<>NEXT_TILE_MSG
STY MSG_ADDR
JSR DISPLAY_MSG
LDX #NEXT_PIECE_LOC
STX CURSORPOS
LDA #`TL_MAP_0_ADDR
STA CURSORPOS + 2
LDA #0
XBA
LDA NEXT_PIECE ; each piece is 16 bytes
ASL A
ASL A
ASL A
ASL A
TAX
DNP_NEXT_PIECE_SYMBOL
LDA PIECE0,X
CMP #0
BEQ DRAW_BLANK
LDA NEXT_PIECE ; skip fist two tiles
CLC
ADC #2
DRAW_BLANK
STA [CURSORPOS]
INX
INC CURSORPOS
LDA #0
STA [CURSORPOS]
INC CURSORPOS
TXA
AND #3
BNE DNP_NEXT_PIECE_SYMBOL
setal
LDA CURSORPOS
CLC
ADC #($40-4) * 2
STA CURSORPOS
TXA
AND #$F
setas
BNE DNP_NEXT_PIECE_SYMBOL
RTS