-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathasmtris.asm
1197 lines (1025 loc) · 26.5 KB
/
asmtris.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
[bits 16]
section .text
mov es, [off_screen]
;timer mem adress
mov ax, 0x0
mov fs, ax
start:
call init
call drawBorder
call drawBackground
call debugDelay
call spawnTetromino
mov ax, [move_n_def]
mov [move_n], ax
call gameLoop
jmp end
init:
;enter video mode 13h (clear screen)
mov ah, 0x0
mov al, 0x13
int 0x10
;disable cursor blinking
mov ax, 0x1003
mov bx, 0
mov bh, 0
int 0x10
;move cursor
mov ah, 0x2
mov bh, 0x0
mov dh, 0x1
mov dl, 0x1
int 0x10
;write ASMTRIS
mov ah, 0xE ;tty mode
mov bl, 0x5 ;purple
mov al, 'A'
int 0x10
mov al, 'S'
int 0x10
mov al, 'M'
int 0x10
mov al, 'T'
int 0x10
mov al, 'R'
int 0x10
mov al, 'I'
int 0x10
mov al, 'S'
int 0x10
call resetScore
call print_controlls
ret
resetScore:
mov [score], word 0
call updateScore
ret
updateScore:
mov ah, 0x2
mov bh, 0x0
mov dh, 0x15
mov dl, 0x1B
int 0x10
mov si, [score_digit]
mov cx, 0
mov ax, [score]
updateScore_dec:
mov bx, 10
mov dx, 0
div bx
add dx, 0x30 ;ascii offset
mov [si], dl ;save char
inc si ;next digit
inc cx ;save digit count
cmp ax, 0
jnz updateScore_dec
dec si
updateScore_print:
mov bl, 0x8
mov ah, 0xE
mov al, [si]
dec si
int 0x10
loop updateScore_print
ret
print_controlls:
mov si, msg_controlls_start
cmp byte [si], 0x2
jne print_controlls_end
mov bl, 0x6
mov cl, 0x3
print_controlls_line:
inc cl
mov ah, 0x2
mov bh, 0x0
mov dh, cl
mov dl, 0x1B
int 0x10
print_controlls_char:
inc si
cmp byte [si], 0xA
je print_controlls_line
cmp byte [si], 0x3
je print_controlls_end
mov ah, 0xE
mov al, [si]
int 0x10
jmp print_controlls_char
print_controlls_end:
ret
gameLoop:
tickLoop_start:
mov cx, [move_n]
tickLoop:
push cx
mov ah, 0x86
mov cx, 0
mov dx, [tick_time]
int 0x15
;keyboard input
call readKeyboard
call check4AdminKeys
call check4Move
pop cx
dec cx
loop tickLoop
call moveTetrominoDown
jmp tickLoop_start
ret
check4AdminKeys:
mov ah, byte [key_scan_code]
cmp ah, byte [key_reset]
je c4A_reset
ret
c4A_reset:
;clear return and bx from loop form stack
pop ax
pop ax
;reset
jmp start
checkFullLine:
;start check at lowest line
mov cx, [t_y_size]
checkFullLine_y_loop:
dec cl
cmp cl, 0
jl checkFullLine_end
mov bl, [t_x_size]
checkFullLine_x_loop:
dec bl
mov [x_draw], bl
mov [y_draw], cl
push bx
call getBlock
pop bx
cmp [outW], word 0 ;check if ther is a free block
je checkFullLine_y_loop ;if so check next line
cmp bl, 0 ;else check next block in line
jge checkFullLine_x_loop
jmp clearFullLine ;full line if no block is free
cmp cl, 0
jge checkFullLine_y_loop
checkFullLine_end:
ret
clearFullLine:
;clear
mov ax, [background_color]
mov [c_draw_i], ax
mov [c_draw_o], ax
xor cx, cx
mov cl, [t_x_size]
clearFullLine_loop:
dec cl
mov [x_draw], cl
push cx
call drawBlock
pop cx
cmp cl, 0
jg clearFullLine_loop
;move every line above one down
xor cx, cx
xor bx, bx
mov cl, [y_draw]
moveLineDown_y_loop:
dec cl
mov [y_draw], cl
mov bl, [t_x_size]
moveLineDown_x_loop:
dec bl
mov [x_draw], bl
push cx
call getColor
pop cx
inc cl
mov [y_draw], cl
dec cl
push cx
call drawBlock
pop cx
mov [y_draw], cl
mov bl, [x_draw]
cmp bl, 0
jg moveLineDown_x_loop
cmp cl, 0
jg moveLineDown_y_loop
jmp checkFullLine
check4Move:
mov ah, byte [key_scan_code]
;cmp ah, byte [key_move_down]
;jne c4M_down_reset
c4M_press:
cmp ah, byte [key_move_left]
je c4M_left
cmp ah, byte [key_move_right]
je c4M_right
cmp ah, byte [key_move_down]
je c4M_down
cmp ah, byte [key_rotate_left]
je c4M_rotate
cmp ah, byte [key_rotate_right]
je c4M_rotate
cmp ah, byte [key_rotate_right_0]
je c4M_rotate
cmp ah, byte [key_hold]
je c4M_hold
ret
;c4M_down_reset:
; mov cx, [move_n_def]
; mov [move_n], cx
; jmp c4M_press
c4M_hold:
cmp [hold_used_flag], byte 1
je c4M_hold_skip
call drawHoldTetromino
mov [hold_used_flag], byte 1 ;set hold used for this block
mov ax, 1
call visibleTetromino ;make invisible
mov si, hold_tetromino_blocks
mov di, tetromino_current_blocks
mov cx, [b_array_size]
shr cx, 1 ;div 2
c4M_hold_loop:
mov ax, [si]
mov bx, [di]
mov [di], ax
mov [si], bx
add si, 2
add di, 2
loop c4M_hold_loop
call drawHoldTetromino
mov ax, [tetromino_rotate_flag] ;copy rotate flag
mov bx, [hold_tetromino_rotate_flag]
mov [hold_tetromino_rotate_flag], ax
mov [tetromino_rotate_flag], bx
cmp byte [hold_full_flag], byte 0
je c4M_hold_new
mov al, [tetromino_x_start]
mov [tetromino_x], al
mov al, [tetromino_y_start]
mov [tetromino_y], al
mov byte [hold_full_flag], byte 1
mov ax, 0
call visibleTetromino
ret
c4M_hold_new:
mov byte [hold_full_flag], byte 1
call spawnTetromino
mov [hold_used_flag], byte 1
ret
c4M_hold_skip:
ret
c4M_left:
mov [tetromino_move_dir], word 1
call moveTetrominoHor
ret
c4M_right:
mov [tetromino_move_dir], word 0
call moveTetrominoHor
ret
c4M_down:
;mov ax, [move_n_def]
;shr ax, 2 ;div 4
;mov ax, 0
;mov [move_n], ax
call moveTetrominoDown
ret
c4M_rotate:
;check rotate flag
mov ax, [tetromino_rotate_flag]
cmp ax, 2
jb c4M_rotate_start ;I -> [tetromino_rotate_flag] = 1 (todo)
ret ;[tetromino_roate_flag] = 2
c4M_rotate_start:
;copy rotated to temp
mov si, tetromino_current_blocks
add si, 2 ;skip color
mov di, tetromino_temp_blocks
mov cx, 4
c4M_rotate_loop:
mov al, byte [si] ;x
inc si
mov bl, byte [si] ;y
inc si
cmp ah, byte [key_rotate_left]
je c4M_rotate_left
neg bl
jmp c4M_rotate_right
c4M_rotate_left:
neg al
c4M_rotate_right:
mov byte [di], bl
inc di
mov byte [di], al
inc di
loop c4M_rotate_loop
jmp c4M_rotate_check
c4M_rotate_check:
;make invisible
mov ax, 1
call visibleTetromino
;check for collision
mov [tetromino_temp_flag], word 1 ;enable temp flag
mov cx, 4
c4M_rotate_loop0:
mov [inW], cx
call getTetrominoBlockPos
call getBlock
cmp [outW], word 0
jne c4M_rotate_exit
loop c4M_rotate_loop0
;no collision - write temp in current
mov si, tetromino_temp_blocks
mov di, tetromino_current_blocks
add di, 2
mov cx, 4
c4M_rotate_loop1:
mov ax, word [si]
mov word [di], ax
add si, 2
add di, 2
loop c4M_rotate_loop1
c4M_rotate_exit:
;make visible
mov ax, 0
call visibleTetromino
mov [tetromino_temp_flag], word 0 ;disable temp flag
ret
readKeyboard:
mov ah, 0x1
int 0x16
jz readKeyboard_no_input
;found a key input
mov byte [key_scan_code], ah
call clearKeyboardBuffer
ret
readKeyboard_no_input:
mov ah, byte 0
mov byte [key_scan_code], ah
ret
clearKeyboardBuffer:
mov ah, 0x1
int 0x16
jz clearKeyboardBuffer_end
;mov [debugPrint_char], al ;debug print ascii key
;call debugPrint
mov ah, 0x0
int 0x16
jmp clearKeyboardBuffer
clearKeyboardBuffer_end:
ret
moveTetrominoHor:
mov ax, 1
call visibleTetromino
mov cx, 4
moveTetrominoHor_check_block:
mov [inW], cx
push cx
call getTetrominoBlockPos
mov ax, [tetromino_move_dir]
cmp ax, 1
je moveTetrominoHor_left
add [x_draw], byte 2
moveTetrominoHor_left:
sub [x_draw], byte 1
pop cx
call getBlock
mov ax, [outW]
cmp ax, 1
je moveTetrominoHor_blocked
cmp ax, 2
je moveTetrominoHor_blocked
loop moveTetrominoHor_check_block
moveTetrominoHor_move:
mov ax, [tetromino_move_dir]
cmp ax, 1
je moveTetrominoHor_move_left
add [tetromino_x], byte 2
moveTetrominoHor_move_left:
sub [tetromino_x], byte 1
call drawTetromino
ret
moveTetrominoHor_blocked:
mov ax, 0
call visibleTetromino
ret
moveTetrominoDown:
mov ax, 1
call visibleTetromino ;make invisible to not detect self
mov cx, 4
moveTetrominoDown_check_block:
mov [inW], cx
call getTetrominoBlockPos
inc byte [y_draw] ;check block below
call getBlock
mov ax, [outW]
cmp ax, 0 ;blocked by other block
jne moveTetrominoDown_blocked
;cmp ax, 2 ;blocked by border
;je moveTetrominoDown_blocked
loop moveTetrominoDown_check_block
moveTetrominoDown_move:
inc word [tetromino_y]
call drawTetromino
ret
moveTetrominoDown_blocked:
mov ax, 0
call visibleTetromino ;make visible
;check full line
call checkFullLine
;spawn new
call spawnTetromino
ret
visibleTetromino: ;ax 1->hidden 0->shown
mov [tetromino_reset_flag], ax
call drawTetromino
ret
getTetrominoBlockPos: ;inW -> block id (1-4)
;tetromino_temp_flag 0 -> current 1 -> temp
;ret x_draw
;ret y_draw
mov ax, [inW]
dec ax
cmp [tetromino_temp_flag], word 0
jne getTetrominoBlockPos_temp
mov si, tetromino_current_blocks
add si, word 2 ;skip color
jmp getTetrominoBlockPos_current
getTetrominoBlockPos_temp:
mov si, tetromino_temp_blocks
getTetrominoBlockPos_current:
add ax, ax
add si, ax ;add block offset
xor ax, ax
xor bx, bx
mov al, byte [si]
mov bl, [tetromino_x]
cmp al, 0
jl getTetrominoBlockPos_neg_x
add bl, al
jmp getTetrominoBlockPos_pos_x
getTetrominoBlockPos_neg_x:
neg al
sub bl, al
getTetrominoBlockPos_pos_x:
mov [x_draw], bl
inc si
xor ax, ax
xor bx, bx
mov al, byte [si]
mov bl, [tetromino_y]
cmp al, 0
jl getTetrominoBlockPos_neg_y
add bl, al
jmp getTetrominoBlockPos_pos_y
getTetrominoBlockPos_neg_y:
neg al
sub bl, al
getTetrominoBlockPos_pos_y:
mov [y_draw], bl
ret
getRandomTetromino:
mov di, [off_timer]
xor ax, ax ;clear ax
mov ax, [fs:di] ;write 2bytes of timer counter into ax
xor dx, dx ;clear dx (needed for %)
mov bx, 7 ;
div bx ;div by 7
mov [tetromino_s], byte dl ;write remainder into [tetromino_s]
cmp dl, 0
je getRandomTetrominoIRotation
cmp dl, 3
je getRandomTetrominoDisableRotation
xor ax, ax ;normal rotation
jmp getRandomTetrominoEnd
getRandomTetrominoIRotation:
mov ax, 1 ;rotation for I tetromino
jmp getRandomTetrominoEnd
getRandomTetrominoDisableRotation:
mov ax, 2 ;no rotation
jmp getRandomTetrominoEnd
getRandomTetrominoEnd:
mov [tetromino_rotate_flag], ax
ret
spawnTetromino:
mov al, [tetromino_x_start]
mov [tetromino_x], al
mov al, [tetromino_y_start]
mov [tetromino_y], al
mov [hold_used_flag], byte 0
call updateScore
call selectTetromino
call drawTetromino
ret
selectTetromino:
call getRandomTetromino
mov si, b_array_start ;set pointer to array
mov ax, 10
mov bl, [tetromino_s] ;
mul bl ;
add si, ax ;shift pointer to selected tetromino
;copy to current_block
mov cx, [b_array_size]
shr cx, 1 ;div array_size by 2 (1 word = 2 byte)
mov di, tetromino_current_blocks ;load mem adress
selectTetromino_loop:
mov ax, word [si] ;read 2 byte from [si]
mov word [di], ax ;write it to [di]
add si, 2 ;inc si by 2
add di, 2 ;inc di by 2
loop selectTetromino_loop
ret
drawTetromino:
mov si, tetromino_current_blocks
mov ax, 0
cmp [tetromino_reset_flag], ax ;check for reset_flag
je drawTetromino_color
mov [tetromino_reset_flag], ax ;reset flag to 0
mov ax, [background_color]
mov [c_draw_i], ax ;more efficent to disable border draw
mov [c_draw_o], ax
add si, 2
jmp drawTetromino_start
drawTetromino_color:
xor ax, ax
mov al, byte [si]
mov [c_draw_i], ax
inc si
xor ax, ax
mov al, byte [si]
mov [c_draw_o], ax
inc si
drawTetromino_start:
mov cx, 4
mov bl, [tetromino_x]
drawTetromino_loop_0:
mov dx, 1
drawTetromino_loop_1:
mov al, byte [si]
cmp al, 0
jl drawTetromino_neg
;positiv
add bl, al
jmp drawTetromino_next
drawTetromino_neg:
neg al
sub bl, al
drawTetromino_next:
inc si
cmp dx, 0
je drawTetromino_y
;x_value
dec dx
mov [x_draw], bl
mov bl, [tetromino_y]
jmp drawTetromino_loop_1
drawTetromino_y:
;y_value
mov [y_draw], bl
push cx ;
call drawBlock ; draw
pop cx ;
mov bl, [tetromino_x]
dec cx
jnz drawTetromino_loop_0
ret
drawHoldTetromino:
mov si, hold_tetromino_blocks
cmp [hold_used_flag], byte 0
je drawHoldTetromino_clear
;color
xor ax, ax
mov al, byte [si]
mov [c_draw_i], ax
inc si
xor ax, ax
mov al, byte [si]
mov [c_draw_o], ax
inc si
jmp drawHoldTetromino_start
drawHoldTetromino_clear:
add si, 2
mov ax, [background_color]
mov [c_draw_i], ax
mov [c_draw_o], ax
drawHoldTetromino_start:
mov [draw_flag], word 2
xor bx, bx
mov cx, 4
drawHoldTetromino_loop:
mov bl, 3
mov al, byte [si]
cmp al, 0
jl drawHoldTetromino_x_neg
;pos
add bl, al
jmp drawHoldTetromino_x_next
drawHoldTetromino_x_neg:
;neg
neg al
sub bl, al
drawHoldTetromino_x_next:
mov [x_draw], byte bl
inc si
mov bl, 3
mov al, byte [si]
cmp al, 0
jl drawHoldTetromino_y_neg
;pos
add bl, al
jmp drawHoldTetromino_y_next
drawHoldTetromino_y_neg:
;neg
neg al
sub bl, al
drawHoldTetromino_y_next:
mov [y_draw], byte bl
inc si
push cx
call drawBlock
pop cx
loop drawHoldTetromino_loop
mov [draw_flag], word 0
ret
drawBorder: ;subroutine to draw border around the game
mov byte [x_draw], 0
mov byte [y_draw], 0
mov ax, [border_color_o]
mov word [c_draw_o], ax
mov ax, [border_color_i]
mov [c_draw_i], ax
mov [draw_flag], word 2
push word [t_x_size]
push word [t_y_size]
mov ax, [x_hold_size]
mov [t_x_size], ax
mov ax, [y_hold_size]
mov [t_y_size], ax
mov cx, 2
drawBorder_loop:
cmp cx, 1
jne drawBorder_loop_hold
pop word [t_y_size]
pop word [t_x_size]
mov [draw_flag], word 1
drawBorder_loop_hold:
push cx
mov cx, [t_x_size]
inc cx
drawBorder_0:
push cx
call drawBlock
pop cx
inc byte [x_draw]
dec cx
jnz drawBorder_0
mov cx, [t_y_size]
inc cx
drawBorder_1:
push cx
call drawBlock
pop cx
inc byte [y_draw]
dec cx
jnz drawBorder_1
mov cx, [t_x_size]
inc cx
drawBorder_2:
push cx
call drawBlock
pop cx
dec byte [x_draw]
dec cx
jnz drawBorder_2
mov cx, [t_y_size]
inc cx
drawBorder_3:
push cx
call drawBlock
pop cx
dec byte [y_draw]
dec cx
jnz drawBorder_3
pop cx
loop drawBorder_loop
mov [draw_flag], word 0
ret
drawBackground:
mov ax, [background_color]
mov [c_draw_o], ax
mov [c_draw_i], ax
mov [draw_flag], word 2
mov ax, [t_x_size]
push ax
mov ax, [t_y_size]
push ax
mov ax, [x_hold_size]
mov [t_x_size], ax
mov ax, [y_hold_size]
mov [t_y_size], ax
mov cx, 2
drawBackground_loop:
cmp cx, 1
jne drawBackground_loop_hold
pop word [t_y_size]
pop word [t_x_size]
mov [draw_flag], word 1
drawBackground_loop_hold:
push cx
mov cx, [t_x_size]
drawBackground_x:
mov [x_draw], cl
push cx
mov cx, [t_y_size]
drawBackground_y:
mov [y_draw], cl
push cx
call drawBlock
pop cx
loop drawBackground_y
pop cx
loop drawBackground_x
pop cx
loop drawBackground_loop
mov [draw_flag], word 0
ret
getColor: ;x_draw
;y_draw
;ret c_draw_i
;ret c_draw_o
call getRealPos
mov di, ax
xor ax, ax
mov al, [es:di]
mov [c_draw_o], ax
add di, [x_screen] ;one down
add di, 1 ;one to the left
mov al, [es:di]
cbw
mov [c_draw_i], ax
ret
getBlock: ;x_draw
;y_draw
;retrun to outW 0->no block 1->block 2->border
cmp [x_draw], byte 0
jl getBlock_border
call getRealPos
mov di, ax
xor ax, ax
mov al, [es:di]
cmp ax, [background_color]
je getBlock_no_block
cmp ax, [border_color_o]
je getBlock_border
;block found
mov ax, 1
mov [outW], ax
ret
getBlock_border:
mov ax, 2
mov [outW], ax
ret
getBlock_no_block:
mov ax, 0
mov [outW], ax
ret
getRealPos: ;x_draw
;y_draw
;ret ax
xor ax, ax
mov al, [y_draw]
mul byte [t_size] ;calc real y pos
add ax, [y_start] ;add y start offset
mul word [x_screen] ;multiply with screen x size
mov bx, ax
xor ax, ax
mov al, [x_draw] ;
mul word [t_size] ;calc real x pos
add ax, [x_start] ;add x start offset
add ax, bx ;sum all together for real x y pos
ret
drawBlock: ; x_draw
; y_draw
; c_draw_o
; c_draw_i
; draw_flag 0 -> normal, 1 -> border, 2 -> holdBorder
mov al, 0
cmp [y_draw], al ;skip if block is to high
jge drawBlock_normal
ret
drawBlock_normal:
call getRealPos
;check draw flag
mov cx, [draw_flag]
cmp cx, 0
je drawBlock_draw_flag_skip
cmp cx, 1
je drawBlock_draw_flag_border
cmp cx, 2
je drawBlock_draw_flag_hold_border
jmp drawBlock_draw_flag_skip
drawBlock_draw_flag_border:
mov bx, ax
mov ax, [x_screen]
mul word [t_size]
add ax, [t_size]
sub bx, ax
mov ax, bx
jmp drawBlock_draw_flag_skip
drawBlock_draw_flag_hold_border:
mov bx, ax
mov ax, [t_size]
mov cx, [x_hold_size]
inc cx
mul cx
mov cx, ax
mov ax, [x_screen]
mul word [t_size]
add ax, [t_size]
add ax, cx
sub bx, ax
mov ax, bx
jmp drawBlock_draw_flag_skip
drawBlock_draw_flag_skip:
mov cx, [t_size]
dec cx
drawBlock_outer0:
mov dl, [c_draw_o]
mov di, ax
mov [es:di], dl
add ax, 1
dec cx
jnz drawBlock_outer0
mov cx, [t_size]
dec cx
drawBlock_outer1:
mov dl, [c_draw_o]
mov di, ax
mov [es:di], dl
add ax, [x_screen]
dec cx
jnz drawBlock_outer1
mov cx, [t_size]
dec cx
drawBlock_outer2:
mov dl, [c_draw_o]
mov di, ax
mov [es:di], dl
sub ax, 1
dec cx