]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/xpal.asm
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / xlib / xpal.asm
1 ;-----------------------------------------------------------------------\r
2 ; MODULE XPAL\r
3 ;\r
4 ; Palette functions all MODE X 256 Color resolutions\r
5 ;\r
6 ; Compile with Tasm.\r
7 ; C callable.\r
8 ;\r
9 ;\r
10 ; ****** XLIB - Mode X graphics library                ****************\r
11 ; ******                                               ****************\r
12 ; ****** Written By Themie Gouthas                     ****************\r
13 ;\r
14 ; egg@dstos3.dsto.gov.au\r
15 ; teg@bart.dsto.gov.au\r
16 ;-----------------------------------------------------------------------\r
17 \r
18 \r
19 COMMENT $\r
20 \r
21 \r
22 \r
23     All the functions in this module operate on two variations of the\r
24     pallete buffer, the raw and annotated buffers.\r
25 \r
26     All those functions ending in buff operate on the following palette\r
27     structure:\r
28 \r
29        BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
30 \r
31     No reference to the starting colour index or number of colours stored\r
32     is contained in the structure.\r
33 \r
34     All those functions ending in struc operate on the following palette\r
35     structure:\r
36 \r
37        BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
38 \r
39     where c is the starting colour and n is the number of colours stored\r
40 \r
41 \r
42     NOTE: previously interrupts were disabled for DAC reads/writes but\r
43           they have been left enabled in this version to allow the mouse\r
44           interrupt to be invoked.\r
45 \r
46 $\r
47 \r
48 \r
49 \r
50 \r
51 include xlib.inc\r
52 include xpal.inc\r
53 \r
54 .code\r
55 \r
56 \r
57 ;----------------------------------------------------------------------\r
58 ; Read DAC palette into annotated type buffer with interrupts disabled\r
59 ; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
60 ;\r
61 ; x_get_pal_struc(char far * pal, int num_colrs, int start_color)\r
62 ;\r
63 ; WARNING: memory for the palette buffers must all be pre-allocated\r
64 ;\r
65 ; Written by Themie Gouthas\r
66 ;----------------------------------------------------------------------\r
67 _x_get_pal_struc  proc\r
68 ;ARG  PalBuff:dword,NumColors:word,StartColor:word\r
69      push  bp           ; Set up stack frame\r
70      mov   bp,sp\r
71      push  di\r
72      push  si\r
73      cld\r
74 \r
75      les   di,dword ptr [bp+4]  ; Point es:di to palette buffer\r
76      mov   si,[bp+10]         ; Store the Start Colour\r
77      mov   ax,si\r
78      stosb\r
79      mov   dx,[bp+8]          ; Store the Number of Colours\r
80      mov   al,dl\r
81      stosb\r
82 \r
83      mov   cx,dx                   ; setup regs and jump\r
84      jmp   short ReadPalEntry\r
85 \r
86 _x_get_pal_struc endp\r
87 \r
88 \r
89 \r
90 \r
91 \r
92 ;----------------------------------------------------------------------\r
93 ; Read DAC palette into raw buffer with interrupts disabled\r
94 ; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
95 ;\r
96 ; x_get_pal_raw(char far * pal, int num_colrs, int start_index)\r
97 ;\r
98 ; WARNING: memory for the palette buffers must all be pre-allocated\r
99 ;\r
100 ; Written by Themie Gouthas\r
101 ;----------------------------------------------------------------------\r
102 _x_get_pal_raw  proc\r
103 ;ARG  PalBuff:dword,NumColors:word,StartColor:word\r
104      push  bp           ; Set up stack frame\r
105      mov   bp,sp\r
106      push  di\r
107      push  si\r
108 \r
109      les   di,dword ptr [bp+4]  ; Point es:di to palette buffer\r
110 \r
111      mov  si,[bp+10]\r
112      mov  cx,[bp+8]\r
113 \r
114 ReadPalEntry:\r
115      cld\r
116      WaitVsyncStart\r
117      mov  ax,si\r
118      mov  dx,DAC_READ_INDEX\r
119      ;cli\r
120      out  dx,al                    ; Tell DAC what colour to start reading\r
121      mov  dx,DAC_DATA\r
122 \r
123      mov  bx,cx                    ; set cx to Num Colors * 3 ( size of\r
124      shl  bx,1                     ; palette buffer)\r
125      add  cx,bx\r
126 \r
127      rep  insb                     ; read the palette enntries\r
128 \r
129      ;sti\r
130      pop  si\r
131      pop  di\r
132      pop  bp\r
133      ret\r
134 _x_get_pal_raw endp\r
135 \r
136 \r
137 \r
138 ;----------------------------------------------------------------------\r
139 ; Write DAC palette from annotated type buffer with interrupts disabled\r
140 ; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
141 ;\r
142 ; x_put_pal_struc(char far * pal)\r
143 ;\r
144 ; Written by Themie Gouthas\r
145 ;----------------------------------------------------------------------\r
146 \r
147 _x_put_pal_struc proc\r
148 ARG     CompPalBuff:dword\r
149         push    bp      ;preserve caller's stack frame\r
150         mov     bp,sp   ;point to local stack frame\r
151         push    ds\r
152         push    si\r
153         cld\r
154         lds     si,[CompPalBuff]   ; load the source compressed colour data\r
155         lodsb                      ; get the colours to skip\r
156         mov     ah,0\r
157         mov     bx,ax              ; skip colours\r
158 \r
159         lodsb                      ; get the count of colours to set\r
160         mov     ah,0\r
161         mov     cx,ax              ; use it as a loop counter\r
162         jmp     short WritePalEntry\r
163 \r
164 _x_put_pal_struc  endp\r
165 \r
166 \r
167 ;----------------------------------------------------------------------\r
168 ; Write DAC palette from annotated type buffer with interrupts disabled\r
169 ; starting at a new palette index\r
170 ;\r
171 ; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
172 ;\r
173 ; x_transpose_pal_struc(char far * pal, int StartColor)\r
174 ;\r
175 ; WARNING: memory for the palette buffers must all be pre-allocated\r
176 ;\r
177 ; Written by Themie Gouthas\r
178 ;----------------------------------------------------------------------\r
179 \r
180 _x_transpose_pal_struc proc\r
181 ARG     CompPalBuff:dword,StartColor:word\r
182         push    bp      ;preserve caller's stack frame\r
183         mov     bp,sp   ;point to local stack frame\r
184         push    ds\r
185         push    si\r
186         cld\r
187         lds     si,[CompPalBuff]   ; load the source compressed colour data\r
188         mov     bx,[StartColor]\r
189         mov     [si],bl\r
190         inc     si\r
191         lodsb                      ; get the count of colours to set\r
192         mov     ah,0\r
193         mov     cx,ax              ; use it as a loop counter\r
194         jmp     short WritePalEntry\r
195 _x_transpose_pal_struc endp\r
196 \r
197 \r
198 ;----------------------------------------------------------------------\r
199 ; Write DAC palette from raw buffer with interrupts disabled\r
200 ; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
201 ;\r
202 ; _x_put_pal_raw(char far * pal, int num_colrs, int start_index)\r
203 ;\r
204 ; Written by Themie Gouthas\r
205 ;----------------------------------------------------------------------\r
206 _x_put_pal_raw  proc\r
207 ARG  PalBuff:dword,NumColors:word,StartColor:word\r
208                 push bp         ; Set up stack frame\r
209                 mov  bp,sp\r
210                 push ds\r
211                 push si\r
212 \r
213                 mov  cx,[NumColors]      ; Number of colours to set\r
214                 mov  bx,[StartColor]\r
215                 lds  si,[PalBuff]        ; ds:si -> palette buffer\r
216 \r
217 \r
218 WritePalEntry:\r
219                 mov  ax,@data\r
220                 mov  es,ax\r
221                 cmp  es:[_VsyncHandlerActive],TRUE\r
222                 jne  @@NoVsyncHandler\r
223 @@WaitForLast:\r
224                 cmp  es:[_VsyncPaletteCount],0\r
225                 jne  @@WaitForLast\r
226                 push cx\r
227                 push es\r
228                 mov  di, offset _VsyncPaletteBuffer\r
229                 mov  ax,3\r
230                 mul  cx\r
231                 mov  cx,ax\r
232                 rep  movsb\r
233                 pop  ds\r
234                 pop  cx\r
235                 mov  [_VsyncPaletteStart],bx\r
236                 mov  [_VsyncPaletteCount],cx\r
237                 jmp  short @@Done\r
238 @@NoVsyncHandler:\r
239 \r
240 \r
241                 or   cx,cx\r
242                 jz   @@Done\r
243                 ;cli\r
244                 cld                      ; Make sure we're going the right way\r
245                 WaitVsyncStart           ; Wait for vert sync to start\r
246                 mov  ax,bx\r
247                 mov  bx,60               ; set the vsync check timer (Vsync\r
248                                          ; is tested for at each bx'th entry to\r
249                                          ; prevent snow 60 is otimum for 10\r
250                                          ; MHz 286 or greater\r
251 \r
252 @@SetLoop:\r
253                 mov  dx,DAC_WRITE_INDEX  ; Tell DAC what colour index to start\r
254                 out  dx,al               ; writing from\r
255                 mov  dx,DAC_DATA\r
256 \r
257                 outsb                    ; Set the red component\r
258                 outsb                    ; Set the green component\r
259                 outsb                    ; Set the blue component\r
260                 inc  al                  ; increment the colour index\r
261                 dec  bx                  ; decrement vsync test counter\r
262                 js   @@test_vsync        ; ready to test for vsync again ?\r
263                 loop @@SetLoop           ; No! - continue loop\r
264                 jmp  short @@Done        ; All colours done\r
265 \r
266 @@test_vsync:\r
267                 mov     dx,INPUT_STATUS_0\r
268                 push    ax               ; save current colour index\r
269 @@Wait:\r
270                 in      al,dx            ; wait for vsync leading edge pulse\r
271                 test    al,08h\r
272                 jz      @@Wait\r
273 \r
274                 pop     ax               ; restore current colour index\r
275                 mov     bx,60            ; reset vsync test counter\r
276                 loop @@SetLoop           ; loop for next colour index\r
277 \r
278 @@Done:\r
279                 ;sti\r
280                 pop  si\r
281                 pop  ds\r
282                 pop  bp\r
283                 ret\r
284 _x_put_pal_raw endp\r
285 \r
286 \r
287 \r
288 ;----------------------------------------------------------------------\r
289 ; Set the RGB setting of a vga color\r
290 ;\r
291 ; _x_set_rgb(unsigned char color, unsigned char R,unsigned char G,\r
292 ;            unsigned char B)\r
293 ;\r
294 ;\r
295 ; Written by Themie Gouthas\r
296 ;----------------------------------------------------------------------\r
297 _x_set_rgb  proc\r
298 ARG  ColorIndex:byte,R:byte,G:byte,B:byte\r
299                 push bp         ; Set up stack frame\r
300                 mov  bp,sp\r
301 \r
302                 mov  al,[ColorIndex]\r
303                 mov  dx,DAC_WRITE_INDEX  ; Tell DAC what colour index to\r
304                 out  dx,al               ; write to\r
305                 mov  dx,DAC_DATA\r
306 \r
307                 mov  al,[R]              ; Set the red component\r
308                 out  dx,al\r
309                 mov  al,[G]              ; Set the green component\r
310                 out  dx,al\r
311                 mov  al,[B]              ; Set the blue component\r
312                 out  dx,al\r
313                 pop  bp\r
314                 ret\r
315 _x_set_rgb endp\r
316 \r
317 \r
318 ;----------------------------------------------------------------------\r
319 ; Rotate annotated palette buffer entries\r
320 ;\r
321 ; x_rot_pal_struc(char far * pal, int direction)\r
322 ;\r
323 ; Direction : 0 = backward 1 = forward\r
324 ;\r
325 ; Written by Themie Gouthas\r
326 ;----------------------------------------------------------------------\r
327 _x_rot_pal_struc  proc\r
328 ARG  PalBuff:dword,Direction:word\r
329     push bp             ; Set up stack frame\r
330     mov  bp,sp\r
331     push ds\r
332     push si\r
333     push di\r
334 \r
335     cld\r
336     lds  si,dword ptr [PalBuff]  ; point ds:si to Palette buffer\r
337     lodsw         ; al = colorst ot skip, ah = num colors\r
338 \r
339     xor  ch,ch    ; Set the number of palette entries to cycle in cx\r
340     mov  cl,ah    ;\r
341 \r
342     jmp  short RotatePalEntry\r
343 \r
344 _x_rot_pal_struc  endp\r
345 \r
346 \r
347 \r
348 ;----------------------------------------------------------------------\r
349 ; Rotate raw palette buffer\r
350 ;\r
351 ; x_rot_pal_raw(char far * pal, int direction, int num_colrs)\r
352 ;\r
353 ; Direcction : 0 = backward 1 = forward\r
354 ;\r
355 ; Written by Themie Gouthas\r
356 ;----------------------------------------------------------------------\r
357 _x_rot_pal_raw  proc\r
358 ARG  PalBuff:dword,Direction:word,NumColors:word\r
359     push bp             ; Set up stack frame\r
360     mov  bp,sp\r
361     push ds\r
362     push si\r
363     push di\r
364 \r
365     cld\r
366     mov  cx,[NumColors]          ; Set the number of palette entries to cycle\r
367     lds  si,dword ptr [PalBuff]  ; point ds:si to Palette buffer\r
368 \r
369 RotatePalEntry:\r
370 \r
371 \r
372     mov  ax,ds                ; copy ds to es\r
373     mov  es,ax\r
374 \r
375     dec  cx\r
376     mov  bx,cx                ; Multiply cx by 3\r
377     shl  bx,1\r
378     add  cx,bx\r
379 \r
380     cmp  [Direction],0        ; are we going forward ?\r
381     jne  @@forward            ; yes - jump (colors move one position back)\r
382 \r
383     std                       ; no - set reverse direction\r
384     add  si,cx                ; set si to last byte in palette\r
385     add  si,2\r
386 \r
387 @@forward:\r
388     mov  ax,si                ; copy si to di\r
389     mov  di,ax\r
390 \r
391     lodsb                     ; load first color triplet into regs\r
392     mov  dl,al\r
393     lodsb\r
394     mov  dh,al\r
395     lodsb\r
396     mov  bl,al\r
397 \r
398     rep  movsb                ; move remaining triplets direction indicated\r
399                               ; by direction flag\r
400 \r
401     mov  al,dl                ; write color triplet from regs to last position\r
402     stosb\r
403     mov  al,dh\r
404     stosb\r
405     mov  al,bl\r
406     stosb\r
407 \r
408     pop  di\r
409     pop  si\r
410     pop  ds\r
411     pop  bp\r
412     ret\r
413 _x_rot_pal_raw  endp\r
414 \r
415 ;----------------------------------------------------------------------\r
416 ; Copy palette making intensity adjustment\r
417 ; x_cpcontrast_pal_struc(char far *src_pal, char far *dest_pal, unsigned char Intensity)\r
418 ;\r
419 ; WARNING: memory for the palette buffers must all be pre-allocated\r
420 ;\r
421 ; Written by Themie Gouthas\r
422 ;----------------------------------------------------------------------\r
423 _x_cpcontrast_pal_struc proc\r
424 ARG  PalSrcBuff:dword,PalDestBuff:dword,Intensity:byte\r
425     push bp             ; Set up stack frame\r
426     mov  bp,sp\r
427     push ds\r
428     push si\r
429     push di\r
430 \r
431     cld\r
432     mov  bh,0ffh\r
433     sub  bh,[Intensity]\r
434     and  bh,07fh            ; Palettes are 7 bit\r
435     lds  si,dword ptr [PalSrcBuff]  ; point ds:si to Source Palette buffer\r
436     les  di,dword ptr [PalDestBuff] ; point ds:si to Source Palette buffer\r
437     lodsw                           ; al = colorst ot skip, ah = num color\r
438     stosw\r
439 \r
440     xor  ch,ch    ; Set the number of palette entries to adjust\r
441     mov  cl,ah    ;\r
442 \r
443     mov  dx,0     ; flag set to 0 if all output palette entries zero\r
444 @@MainLoop:\r
445     lodsw\r
446     sub  al,bh               ; adjust intensity and copy RED\r
447     jns  @@DecrementOK_R\r
448     xor  al,al\r
449 @@DecrementOK_R:\r
450     sub  ah,bh               ; adjust intensity and copy GREEN\r
451     jns  @@DecrementOK_G\r
452     xor  ah,ah\r
453 @@DecrementOK_G:\r
454     or   dx,ax\r
455     or   dl,ah\r
456     stosw\r
457     lodsb\r
458     sub  al,bh               ; adjust intensity and copy BLUE\r
459     jns  @@DecrementOK_B\r
460     xor  al,al\r
461 @@DecrementOK_B:\r
462     or   dl,al\r
463     stosb\r
464     loop @@MainLoop\r
465 \r
466     mov  ax,dx\r
467     pop  di\r
468     pop  si\r
469     pop  ds\r
470     pop  bp\r
471     ret\r
472 _x_cpcontrast_pal_struc  endp\r
473 \r
474 \r
475 \r
476 ;----------------------------------------------------------------------\r
477 ; Write DAC palette from annotated type buffer with specified intensity\r
478 ; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
479 ;\r
480 ; x_put_contrast_pal_struc(char far * pal, unsigned char  intensity)\r
481 ;\r
482 ; Designed for fading in or out a palette without using an intermediate\r
483 ; working palette buffer ! (Slow but memory efficient ... OK for small\r
484 ; pal strucs}\r
485 ;\r
486 ; Written by Themie Gouthas\r
487 ;----------------------------------------------------------------------\r
488 \r
489 _x_put_contrast_pal_struc proc\r
490 ARG     CompPalBuff:dword,Intensity:byte\r
491         push    bp      ;preserve caller's stack frame\r
492         mov     bp,sp   ;point to local stack frame\r
493         push    ds\r
494         push    si\r
495         push    di\r
496         cld\r
497 \r
498         mov     bh,0ffh\r
499         sub     bh,[Intensity]\r
500         and     bh,07fh            ; Palettes are 7 bit\r
501         mov     di,40              ; set the vsync check timer (Vsync\r
502                                    ; is tested for at each di'th entry to\r
503                                    ; prevent snow 40 is otimum for 10\r
504                                    ; MHz 286 or greater)\r
505         lds     si,[CompPalBuff]   ; load the source compressed colour data\r
506         lodsb                      ; get the colours to skip\r
507         mov     bl,al\r
508 \r
509         lodsb                      ; get the count of colours to set\r
510         mov     ah,0\r
511         mov     cx,ax              ; use it as a loop counter\r
512         or      cx,cx\r
513         jz      @@Done\r
514 \r
515         WaitVsyncStart           ; Wait for vert sync to start\r
516 \r
517 @@MainLoop:\r
518         mov  al,bl\r
519         mov  dx,DAC_WRITE_INDEX  ; Tell DAC what colour index to start\r
520         out  dx,al               ; writing from\r
521         inc  dx                  ; == mov  dx,DAC_DATA\r
522 \r
523         lodsb                    ; Load each colour component, modify for\r
524         sub  al,bh               ; intensity and write to DAC H/Ware\r
525         jns  @@DecrementOK_R\r
526         xor  al,al\r
527 @@DecrementOK_R:\r
528         out  dx,al\r
529 \r
530         lodsb\r
531         sub  al,bh\r
532         jns  @@DecrementOK_G\r
533         xor  al,al\r
534 @@DecrementOK_G:\r
535         out  dx,al\r
536 \r
537         lodsb\r
538         sub  al,bh\r
539         jns  @@DecrementOK_B\r
540         xor  al,al\r
541 @@DecrementOK_B:\r
542         out  dx,al\r
543 \r
544         inc  bl                  ; increment color index\r
545         dec  di                  ; decrement vsync test flag\r
546         js   @@test_vsync\r
547         loop @@MainLoop\r
548         jmp  short @@Done\r
549 \r
550 \r
551 @@test_vsync:\r
552         mov     dx,INPUT_STATUS_0\r
553         push    ax               ; save current colour index\r
554 @@Wait:\r
555         in      al,dx            ; wait for vsync leading edge pulse\r
556         test    al,08h\r
557         jz      @@Wait\r
558 \r
559         pop     ax               ; restore current colour index\r
560         mov     di,40            ; reset vsync test counter\r
561         loop    @@MainLoop       ; loop for next colour index\r
562 \r
563 @@Done:\r
564         ;sti\r
565         pop  di\r
566         pop  si\r
567         pop  ds\r
568         pop  bp\r
569         ret\r
570 \r
571 _x_put_contrast_pal_struc   endp\r
572 \r
573 \r
574     end\r
575 \r
576 \r