1 ;-----------------------------------------------------------------------
\r
3 ; This module was written by Matthew MacKenzie
\r
6 ; Compiled bitmap functions all MODE X 256 Color resolutions
\r
11 ; ****** XLIB - Mode X graphics library ****************
\r
12 ; ****** ****************
\r
13 ; ****** Written By Themie Gouthas ****************
\r
14 ; ****** Aeronautical Research Laboratory ****************
\r
15 ; ****** Defence Science and Technology Organisation ****************
\r
16 ; ****** Australia ****************
\r
18 ; egg@dstos3.dsto.gov.au
\r
19 ; teg@bart.dsto.gov.au
\r
20 ;-----------------------------------------------------------------------
\r
23 include xcbitmap.inc
\r
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
\r
28 ; Compile a linear bitmap to generate machine code to plot it
\r
29 ; at any required screen coordinates FAST. Faster than blits
\r
30 ; using planar bitmaps as in module XPBIITMAP
\r
32 ; C near-callable as:
\r
33 ; int x_compile_bitmap (WORD logical_screen_width,
\r
34 ; char far * bitmap, char far * output);
\r
36 ; The logical width is in bytes rather than pixels.
\r
38 ; All four main registers are totaled.
\r
40 ; The source linear bitmaps have the following structure:
\r
42 ; BYTE 0 The bitmap width in pixels range 1..255
\r
43 ; BYTE 1 The bitmap height in rows range 1..255
\r
44 ; BYTE 2..n The width*height bytes of the bitmap in
\r
47 ; The returned value is the size of the compiled bitmap, in bytes.
\r
50 ; accessory macros to save typing (what else?)
\r
52 mov byte ptr es:[di],&arg&
\r
57 mov word ptr es:[di],&arg&
\r
61 ; opcodes emitted by _x_compile_sprite
\r
62 ROL_AL equ 0c0d0h ; rol al
\r
63 SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8
\r
64 STORE_8 equ 084c6h ; mov [si]+disp16, imm8
\r
65 SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16
\r
66 STORE_16 equ 084c7h ; mov [si]+disp16, imm16
\r
67 ADC_SI_IMMED equ 0d683h ; adc si,imm8
\r
68 OUT_AL equ 0eeh ; out dx,al
\r
69 RETURN equ 0cbh ; ret
\r
75 ColumnMask db 011h,022h,044h,088h
\r
81 _x_compile_bitmap proc
\r
82 ARG logical_width:word,bitmap:dword,output:dword
\r
83 LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
\r
85 mov bp, sp ; caller's stack frame
\r
86 sub sp,LocalStk ; local space
\r
91 mov word ptr [scanx],0
\r
92 mov word ptr [scany],0
\r
93 mov word ptr [outputx],0
\r
94 mov word ptr [outputy],0
\r
95 mov word ptr [column],0
\r
96 mov word ptr [set_column],0
\r
98 lds si,[bitmap] ; 32-bit pointer to source bitmap
\r
100 les di,[output] ; 32-bit pointer to destination stream
\r
102 lodsb ; load width byte
\r
103 xor ah, ah ; convert to word
\r
104 mov [bwidth], ax ; save for future reference
\r
105 mov bl, al ; copy width byte to bl
\r
106 lodsb ; load height byte -- already a word since ah=0
\r
107 mul bl ; mult height word by width byte
\r
108 mov [input_size], ax; to get pixel total
\r
111 mov bx, [scanx] ; position in original bitmap
\r
114 mov al, [si+bx] ; get pixel
\r
115 or al, al ; skip empty pixels
\r
120 mov dx, [set_column]
\r
124 Emitw ROL_AL ; emit code to move to new column
\r
132 Emitb OUT_AL ; emit code to set VGA mask for new column
\r
133 mov [set_column], dx
\r
135 mov dx, [outputy] ; calculate output position
\r
139 add word ptr [scanx], 4
\r
140 mov cx, [scanx] ; within four pixels of right edge?
\r
144 inc word ptr [outputx]
\r
145 mov ah, [si+bx+4] ; get second pixel
\r
149 cmp dx, 127 ; can we use shorter form?
\r
153 Emitw SHORT_STORE_8
\r
154 Emitb dl ; 8-bit position in output
\r
158 Emitw dx ; position in output
\r
161 jmp short @@Advance
\r
167 Emitw SHORT_STORE_16
\r
168 Emitb dl ; 8-bit position in output
\r
169 jmp @@EmitTwoPixels
\r
172 Emitw dx ; position in output
\r
177 inc word ptr [outputx]
\r
183 add dx, [logical_width]
\r
186 cmp cx, [input_size]
\r
188 inc word ptr [column]
\r
191 je @@Exit ; Column 4: there is no column 4.
\r
192 xor cx, cx ; scany and outputy are 0 again for
\r
193 mov dx, cx ; the new column
\r
197 mov word ptr [outputx], 0
\r
206 sub ax,word ptr [output] ; size of generated code
\r
215 _x_compile_bitmap endp
\r
218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
\r
219 ; _x_sizeof_cbitmap
\r
221 ; This function follows the same algorithm as the one above,
\r
222 ; but does not generate a new object. Its sole purpose is to
\r
223 ; determine how much space the compiled bitmap will require.
\r
225 ; C near-callable as:
\r
226 ; int x_sizeof_cbitmap (WORD logical_screen_width,
\r
227 ; char far * bitmap);
\r
229 ; The logical width is in bytes rather than pixels.
\r
231 ; All four main registers are totaled.
\r
233 ; The source linear bitmaps have the following structure:
\r
235 ; BYTE 0 The bitmap width in pixels range 1..255
\r
236 ; BYTE 1 The bitmap height in rows range 1..255
\r
237 ; BYTE 2..n The width*height bytes of the bitmap in
\r
240 ; The returned value is the size of the compiled bitmap, in bytes.
\r
244 _x_sizeof_cbitmap proc
\r
245 ARG logical_width:word,bitmap:dword
\r
246 LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
\r
248 mov bp, sp ; caller's stack frame
\r
249 sub sp,LocalStk ; local space
\r
254 mov word ptr [scanx], 0
\r
255 mov word ptr [scany], 0
\r
256 mov word ptr [outputx], 0
\r
257 mov word ptr [outputy], 0
\r
258 mov word ptr [column], 0
\r
259 mov word ptr [set_column], 0
\r
261 lds si,[bitmap] ; 32-bit pointer to source bitmap
\r
263 mov di, 1 ; initial size is just the size of the far RET
\r
265 lodsb ; load width byte
\r
266 xor ah, ah ; convert to word
\r
267 mov [bwidth], ax ; save for future reference
\r
268 mov bl, al ; copy width byte to bl
\r
269 lodsb ; load height byte -- already a word since ah=0
\r
270 mul bl ; mult height word by width byte
\r
271 mov [input_size], ax; to get pixel total
\r
274 mov bx, [scanx] ; position in original bitmap
\r
277 mov al, [si+bx] ; get pixel
\r
278 or al, al ; skip empty pixels
\r
283 mov dx, [set_column]
\r
287 add di, 5 ; size of code to move to new column
\r
292 inc di ; size of code to set VGA mask
\r
293 mov [set_column], dx
\r
295 mov dx, [outputy] ; calculate output position
\r
299 add word ptr [scanx], 4
\r
300 mov cx, [scanx] ; within four pixels of right edge?
\r
304 inc word ptr [outputx]
\r
305 mov ah,[si+bx+4] ; get second pixel
\r
309 cmp dx, 127 ; can we use shorter form?
\r
313 add di, 4 ; size of 8-bit position in output plus one pixel
\r
316 add di, 5 ; size of position in output plus one pixels
\r
318 jmp short @@Advance
\r
324 add di, 5 ; size of 8-bit position in output plus two pixels
\r
325 jmp @@EmitTwoPixels
\r
327 add di, 6 ; size of 16-bit position in output plus two pixels
\r
331 inc word ptr [outputx]
\r
337 add dx, [logical_width]
\r
340 cmp cx, [input_size]
\r
342 inc word ptr [column]
\r
345 je @@Exit ; Column 4: there is no column 4.
\r
346 xor cx,cx ; scany and outputy are 0 again for
\r
347 mov dx,cx ; the new column
\r
351 mov word ptr [outputx], 0
\r
358 mov ax, di ; size of generated code
\r
367 _x_sizeof_cbitmap endp
\r
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
\r
373 ; Displays a compiled bitmap generated by x_compile_bitmap at given
\r
374 ; coordinates, on a given screen page.
\r
376 ; C near-callable as:
\r
377 ; void x_put_cbitmap (int XPos, int YPos,
\r
378 ; unsigned int PageOffset, char far * Sprite);
\r
379 ; ax, bx, cx, and dx are squashed like insignificant insects.
\r
382 _x_put_cbitmap proc
\r
383 ARG XPos:word,YPos:word,PageOffset:word,Sprite:dword
\r
390 mov ax, [_ScrnLogicalByteWidth] ; global Xlib variable
\r
391 mul word ptr [YPos] ; height in bytes
\r
394 sar si, 2 ; width in bytes
\r
396 add si, [PageOffset]; (YPos * screen width) +
\r
397 add si, 128 ; (Xpos / 4) + page base + 128 ==> starting pos
\r
400 mov ah, ColumnMask[bx]
\r
405 inc dx ; ready to send out other masks as bytes
\r
409 mov ds, bx ; We do this so the compiled shape won't need
\r
410 ; segment overrides.
\r
412 call dword ptr [Sprite] ; the business end of the routine
\r
419 _x_put_cbitmap endp
\r