/
cgalib_blit8x8.asm
222 lines (200 loc) · 4.18 KB
/
cgalib_blit8x8.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
section .text
;;;; blit_tile8XY : Blit a 8x8 tile to a destination coordinate
;
; ds:si : Pointer to tile data
; es:di : Video memory base (b800:0)
; ax: X coordinate (in pixels) (ANDed with 0xfffc)
; bx: Y coordinate (in pixels) (ANDed with 0xfffe)
blit_tile8XY:
push ax
push bx
push cx
push dx ; clobbered by MUL
push di
mov di, bx
shl di, 1
add di, cgarows
mov di, [di]
; X /= 4 (4 pixel per memory byte)
mov cl, al
and cl, 03h
shr ax, 1
shr ax, 1
add di, ax ; Offset in line
; Y /= 2 (only support even scanlines)
; shr bx, 1
; pushf
; Y *=80 (skip to target row)
; mov ax, 80
; mul bx
; add di, ax
; popf
test di, 0x2000
jnz _bt8_odd
call blit_tile8_even_y
pop di
pop dx
pop cx
pop bx
pop ax
ret
_bt8_odd:
call blit_tile8_odd_y
pop di
pop dx
pop cx
pop bx
pop ax
ret
;;;; blit_tile8 : Blit a 8x8 tile to a specified screen location.
; ds:si : Pointer to tile data
; es:di : Offset (in video memory) (Note: Must be on an even line)
;
; cl: X offset (0-3)
;
; Due to the CGA low-res packing arrangement, the offset value given
; in byte places the tile on a grid of 4 pixels.
blit_tile8_even_y:
push si
push di
cmp cl, 1
je blit_tile8_even_y_x1
cmp cl, 2
je blit_tile8_even_y_x2
cmp cl, 3
je blit_tile8_even_y_x3
%macro movsw_post_add 1
movsw
add di, %1
%endmacro
movsw_post_add 78
movsw_post_add 78
movsw_post_add 78
movsw_post_add 0x2000 - (80*3) -2
movsw_post_add 78
movsw_post_add 78
movsw_post_add 78
movsw
pop di
pop si
ret
blit_tile8_odd_y:
push si
push di
cmp cl, 1
je blit_tile8_odd_y_x1
cmp cl, 2
je blit_tile8_odd_y_x2
cmp cl, 3
je blit_tile8_odd_y_x3
; add di, 0x2000
movsw_post_add 78
movsw_post_add 78
movsw_post_add 78
movsw
sub di, 0x2000 + 80*2 + 2
movsw_post_add 78
movsw_post_add 78
movsw_post_add 78
movsw
pop di
pop si
ret
;;; X=1
blit_tile8_even_y_x1:
mov cl, 2 ; shift
%macro cpWord_extra_byte_and_add 2
lodsb
xchg ah, al
lodsb
mov bl, al
shr ax, cl
xchg ah, al
stosw
ror bl, cl
and bl, %2
mov al, bl
stosb
add di, %1
%endmacro
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 0x2000 - (80 * 3) - 3 , 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
pop di
pop si
ret
;;; X=2
blit_tile8_even_y_x2:
mov cl, 4 ; shift
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 0x2000 - (80 * 3) - 3 , 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
pop di
pop si
ret
;;; X=3
blit_tile8_even_y_x3:
mov cl, 6 ; shift
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 0x2000 - (80 * 3) - 3 , 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
pop di
pop si
ret
;;; X=1
blit_tile8_odd_y_x1:
mov cl, 2 ; shift
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 0xE000 - (80 * 2) - 3 , 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
cpWord_extra_byte_and_add 77, 0xC0
pop di
pop si
ret
;;; X=2
blit_tile8_odd_y_x2:
mov cl, 4 ; shift
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 0xE000 - (80 * 2) - 3 , 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
cpWord_extra_byte_and_add 77, 0xF0
pop di
pop si
ret
;;; X=3
blit_tile8_odd_y_x3:
mov cl, 6 ; shift
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 0xE000 - (80 * 2) - 3 , 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
cpWord_extra_byte_and_add 77, 0xFC
pop di
pop si
ret