OSDN Git Service

update todo list with new stuff
[proj16/16.git] / 16 / xlib / xcomppbm.asm
1 ;-----------------------------------------------------------------------\r
2 ; module XCOMPPBM\r
3 ;\r
4 ; This module contains only the compiler and sizeof routines --\r
5 ; use the plotter from XCBITMAP.\r
6 ;\r
7 ;-----------------------------------------------------------------------\r
8 \r
9 include xlib.inc\r
10 include xcomppbm.inc\r
11 \r
12 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
13 ; _x_compile_pbm\r
14 ;\r
15 ; I only changed five instructions, instead of rewriting this\r
16 ; for PBMs.  So it is amazingly inefficient.  But, what the hell,\r
17 ; It's only a game :).\r
18 ;\r
19 \r
20 ; accessory macros to save typing (what else?)\r
21 Emitb macro arg\r
22         mov byte ptr es:[di],&arg&\r
23         inc di\r
24         endm\r
25 \r
26 Emitw macro arg\r
27         mov word ptr es:[di],&arg&\r
28         add di,2\r
29         endm\r
30 \r
31 ; opcodes emitted by _x_compile_pbm\r
32 ROL_AL          equ 0c0d0h              ; rol al\r
33 SHORT_STORE_8   equ 044c6h              ; mov [si]+disp8,  imm8\r
34 STORE_8         equ 084c6h              ; mov [si]+disp16, imm8\r
35 SHORT_STORE_16  equ 044c7h              ; mov [si]+disp8,  imm16\r
36 STORE_16        equ 084c7h              ; mov [si]+disp16, imm16\r
37 ADC_SI_IMMED    equ 0d683h              ; adc si,imm8\r
38 OUT_AL          equ 0eeh                ; out dx,al\r
39 RETURN          equ 0cbh                ; ret\r
40 \r
41 \r
42 .data\r
43 \r
44 align 2\r
45 ColumnMask      db      011h,022h,044h,088h\r
46 \r
47 \r
48 .code\r
49 \r
50         align   2\r
51 _x_compile_pbm proc\r
52 ARG   logical_width:word,bitmap:dword,output:dword\r
53 LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
54         push bp\r
55         mov  bp, sp         ; caller's stack frame\r
56         sub  sp,LocalStk    ; local space\r
57         push si\r
58         push di\r
59         push ds\r
60 \r
61         mov word ptr [scanx],0\r
62         mov word ptr [scany],0\r
63         mov word ptr [outputx],0\r
64         mov word ptr [outputy],0\r
65         mov word ptr [column],0\r
66         mov word ptr [set_column],0\r
67 \r
68         lds si,[bitmap]     ; 32-bit pointer to source bitmap\r
69 \r
70         les di,[output]     ; 32-bit pointer to destination stream\r
71 \r
72         lodsb               ; load width byte\r
73         xor ah, ah          ; convert to word\r
74         mov [bwidth], ax    ; save for future reference\r
75         mov bl, al          ; copy width byte to bl\r
76         lodsb               ; load height byte -- already a word since ah=0\r
77         mul bl              ; mult height word by width byte\r
78         mov [input_size], ax;  to get pixel total\r
79 \r
80 @@MainLoop:\r
81         mov bx, [scanx]     ; position in original bitmap\r
82         add bx, [scany]\r
83 \r
84         mov al, [si+bx]     ; get pixel\r
85         or  al, al          ; skip empty pixels\r
86         jnz @@NoAdvance\r
87         jmp @@Advance\r
88 @@NoAdvance:\r
89 \r
90         mov dx, [set_column]\r
91         cmp dx, [column]\r
92         je @@SameColumn\r
93 @@ColumnLoop:\r
94         Emitw ROL_AL        ; emit code to move to new column\r
95         Emitw ADC_SI_IMMED\r
96         Emitb 0\r
97 \r
98         inc dx\r
99         cmp dx, [column]\r
100         jl @@ColumnLoop\r
101 \r
102         Emitb OUT_AL        ; emit code to set VGA mask for new column\r
103         mov [set_column], dx\r
104 @@SameColumn:\r
105         mov dx, [outputy]   ; calculate output position\r
106         add dx, [outputx]\r
107         sub dx, 128\r
108 \r
109         inc word ptr [scanx]\r
110         mov cx, [scanx]     ; within four pixels of right edge?\r
111         cmp cx, [bwidth]\r
112         jge @@OnePixel\r
113 \r
114         inc word ptr [outputx]\r
115         mov ah, [si+bx+1]   ; get second pixel\r
116         or ah, ah\r
117         jnz @@TwoPixels\r
118 @@OnePixel:\r
119         cmp dx, 127         ; can we use shorter form?\r
120         jg @@OnePixLarge\r
121         cmp dx, -128\r
122         jl @@OnePixLarge\r
123         Emitw SHORT_STORE_8\r
124         Emitb dl            ; 8-bit position in output\r
125         jmp @@EmitOnePixel\r
126 @@OnePixLarge:\r
127         Emitw STORE_8\r
128         Emitw dx            ; position in output\r
129 @@EmitOnePixel:\r
130         Emitb al\r
131         jmp short @@Advance\r
132 @@TwoPixels:\r
133         cmp dx, 127\r
134         jg @@TwoPixLarge\r
135         cmp dx, -128\r
136         jl @@TwoPixLarge\r
137         Emitw SHORT_STORE_16\r
138         Emitb dl            ; 8-bit position in output\r
139         jmp @@EmitTwoPixels\r
140 @@TwoPixLarge:\r
141         Emitw STORE_16\r
142         Emitw dx            ; position in output\r
143 @@EmitTwoPixels:\r
144         Emitw ax\r
145 \r
146 @@Advance:\r
147         inc word ptr [outputx]\r
148         mov ax, [scanx]\r
149         inc ax\r
150         cmp ax, [bwidth]\r
151         jl @@AdvanceDone\r
152         mov dx, [outputy]\r
153         add dx, [logical_width]\r
154         mov cx, [scany]\r
155         add cx, [bwidth]\r
156         cmp cx, [input_size]\r
157         jl @@NoNewColumn\r
158         inc word ptr [column]\r
159         mov cx, [column]\r
160         cmp cx, 4\r
161         je @@Exit           ; Column 4: there is no column 4.\r
162         xor cx, cx          ; scany and outputy are 0 again for\r
163         mov dx, cx          ; the new column\r
164         add si, [input_size]\r
165 @@NoNewColumn:\r
166         mov [outputy], dx\r
167         mov [scany], cx\r
168         xor ax, ax\r
169         mov word ptr [outputx], 0\r
170 @@AdvanceDone:\r
171         mov [scanx], ax\r
172         jmp @@MainLoop\r
173 \r
174 @@Exit:\r
175         Emitb RETURN\r
176         mov ax,di\r
177         sub ax,word ptr [output] ; size of generated code\r
178 \r
179         pop ds\r
180         pop di\r
181         pop si\r
182         mov sp, bp\r
183         pop bp\r
184 \r
185         ret\r
186 _x_compile_pbm endp\r
187 \r
188 \r
189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
190 ; _x_sizeof_cpbm\r
191 ;\r
192 \r
193 \r
194         align   2\r
195 _x_sizeof_cpbm proc\r
196 ARG   logical_width:word,bitmap:dword\r
197 LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
198         push bp\r
199         mov  bp, sp         ; caller's stack frame\r
200         sub  sp,LocalStk    ; local space\r
201         push si\r
202         push di\r
203         push ds\r
204 \r
205         mov word ptr [scanx], 0\r
206         mov word ptr [scany], 0\r
207         mov word ptr [outputx], 0\r
208         mov word ptr [outputy], 0\r
209         mov word ptr [column], 0\r
210         mov word ptr [set_column], 0\r
211 \r
212         lds si,[bitmap]     ; 32-bit pointer to source bitmap\r
213 \r
214         mov di, 1           ; initial size is just the size of the far RET\r
215 \r
216         lodsb               ; load width byte\r
217         xor ah, ah          ; convert to word\r
218         mov [bwidth], ax    ; save for future reference\r
219         mov bl, al          ; copy width byte to bl\r
220         lodsb               ; load height byte -- already a word since ah=0\r
221         mul bl              ; mult height word by width byte\r
222         mov [input_size], ax;  to get pixel total\r
223 \r
224 @@MainLoop:\r
225         mov bx, [scanx]     ; position in original bitmap\r
226         add bx, [scany]\r
227 \r
228         mov al, [si+bx]     ; get pixel\r
229         or  al, al          ; skip empty pixels\r
230         jnz @@NoAdvance\r
231         jmp @@Advance\r
232 @@NoAdvance:\r
233 \r
234         mov dx, [set_column]\r
235         cmp dx, [column]\r
236         je @@SameColumn\r
237 @@ColumnLoop:\r
238         add di, 5           ; size of code to move to new column\r
239         inc dx\r
240         cmp dx,[column]\r
241         jl @@ColumnLoop\r
242 \r
243         inc di              ; size of code to set VGA mask\r
244         mov [set_column], dx\r
245 @@SameColumn:\r
246         mov dx, [outputy]   ; calculate output position\r
247         add dx, [outputx]\r
248         sub dx, 128\r
249 \r
250         inc word ptr [scanx]\r
251         mov cx, [scanx]     ; within four pixels of right edge?\r
252         cmp cx, [bwidth]\r
253         jge @@OnePixel\r
254 \r
255         inc word ptr [outputx]\r
256         mov ah,[si+bx+1]    ; get second pixel\r
257         or ah, ah\r
258         jnz @@TwoPixels\r
259 @@OnePixel:\r
260         cmp dx, 127         ; can we use shorter form?\r
261         jg @@OnePixLarge\r
262         cmp dx, -128\r
263         jl @@OnePixLarge\r
264         add di, 4           ; size of 8-bit position in output plus one pixel\r
265         jmp @@EmitOnePixel\r
266 @@OnePixLarge:\r
267         add di, 5           ; size of position in output plus one pixels\r
268 @@EmitOnePixel:\r
269         jmp short @@Advance\r
270 @@TwoPixels:\r
271         cmp dx, 127\r
272         jg @@TwoPixLarge\r
273         cmp dx, -128\r
274         jl @@TwoPixLarge\r
275         add di, 5           ; size of 8-bit position in output plus two pixels\r
276         jmp @@EmitTwoPixels\r
277 @@TwoPixLarge:\r
278         add di, 6           ; size of 16-bit position in output plus two pixels\r
279 @@EmitTwoPixels:\r
280 \r
281 @@Advance:\r
282         inc word ptr [outputx]\r
283         mov ax, [scanx]\r
284         inc ax\r
285         cmp ax, [bwidth]\r
286         jl @@AdvanceDone\r
287         mov dx, [outputy]\r
288         add dx, [logical_width]\r
289         mov cx, [scany]\r
290         add cx, [bwidth]\r
291         cmp cx, [input_size]\r
292         jl @@NoNewColumn\r
293         inc word ptr [column]\r
294         mov cx, [column]\r
295         cmp cx, 4\r
296         je @@Exit           ; Column 4: there is no column 4.\r
297         xor cx,cx           ; scany and outputy are 0 again for\r
298         mov dx,cx           ; the new column\r
299         add si, [input_size]\r
300 @@NoNewColumn:\r
301         mov [outputy], dx\r
302         mov [scany], cx\r
303         xor ax, ax\r
304         mov word ptr [outputx], ax\r
305 @@AdvanceDone:\r
306         mov [scanx], ax\r
307         jmp @@MainLoop\r
308 \r
309 @@Exit:\r
310         mov ax, di          ; size of generated code\r
311 \r
312         pop ds\r
313         pop di\r
314         pop si\r
315         mov sp,bp\r
316         pop bp\r
317 \r
318         ret\r
319 _x_sizeof_cpbm endp\r
320 \r
321 end\r
322 \r