source: abuse/tags/pd/imlib/port/oldports/vid_dos.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1#include "globals.hpp"
2#include "system.h"
3#include "video.hpp"
4#include "dos.h"
5#include "xinclude.h"
6#include "macs.hpp"
7#include "bitmap.h"
8#include "image.hpp"
9
10//#define DIRECT_SCREEN
11
12
13#define CGAY(y) ((y%2)?(y/2)*80:0x2000+((y-1)/2)*80)
14
15unsigned char current_background;
16extern unsigned int xres,yres;
17int xoff,yoff,vmode;
18image *screen;
19
20int get_vmode()
21{ return vmode; }
22
23
24void set_mode(int mode, int argc, char **argv)
25{
26  unsigned char *page;
27
28  vmode=mode;
29  int i,fail;
30  for (i=1,fail=0;i<argc && !fail;i++)
31    if (!strcmp(argv[i],"-vmode"))
32    {
33      if (i==argc-1) fail=1;
34      else
35      { if (!strcmp(argv[i+1],"VGA_320x200x256"))
36          mode=19;
37        else if (!strcmp(argv[i+1],"TRI_640x480x256"))
38          mode=TRI_640x480x256;
39        else if (!strcmp(argv[i+1],"TRI_800x600x256"))
40          mode=TRI_800x600x256;
41        else if (!strcmp(argv[i+1],"TRI_1024x768x256"))
42          mode=TRI_1024x768x256;
43        else if (!strcmp(argv[i+1],"CGA_640x200x2"))
44          mode=CGA_640x200x2;
45        else fail=1;
46      }
47    }
48  if (fail)
49  {
50    printf("Expected one of the folloing video modes after -vmode switch\n"
51           "  CGA_640x200x2      CGA 2 color graphics (dithered imaging)\n"
52           "  VGA_320x200x256    Standard vga 256 color mode\n"
53           "  TRI_640x480x256    Trident super vga\n"
54           "  TRI_800x640x256    Trident super vga\n"
55           "  TRI_1024x768x256   Trident super vga (1 meg video memory needed)\n"
56           "example : %s -vmode VGA_320x200x256\n",argv[0]);
57    exit(0);
58  }
59  vmode=mode;
60  switch (mode)
61  {
62    case TRI_1024x768x256 : xres=1023; yres=767; break;
63    case TRI_800x600x256  : xres=799;  yres=599; break;
64    case TRI_640x480x256  : xres=639;  yres=479; break;
65    case VGA_320x200x256  : xres=319;  yres=199; break;
66    case CGA_640x200x2    : xres=639;  yres=199; break;
67  }
68  asm {
69    mov ax, mode
70    int 0x10
71  }
72  page=NULL;
73#ifdef DIRECT_SCREEN
74  if (mode==19)
75    page=(unsigned char *)MK_FP(0xa000,0);
76#endif
77  screen=new image(xres+1,yres+1,page,2);
78  screen->clear();
79  update_dirty(screen);
80}
81
82void close_graphics()
83{
84  asm {
85    mov ax, 3
86    int 0x10
87  }
88}
89
90
91void put_image(image *im, int x, int y)
92{
93  int ls,iy,i,w;
94  unsigned int sp;
95  long off;
96  char *sl;
97  ls=-1;
98  iy=0;
99  w=im->width();
100  while (iy<im->height())
101  {
102    sl=im->scan_line(iy++);
103    if (vmode==CGA_640x200x2)
104    {
105      int byte_off,bit_off;
106      char compsl[80];
107      byte_off=0;
108
109      compsl[0]=peekb(0xb800,CGAY(y)+x/8);
110      compsl[(w-2)/8]=peekb(0xb800,CGAY(y)+(x+w-2)/8);
111      bit_off=128>>(x%8);
112      for (i=0;i<w;i++)
113      {
114        if (!sl[i])
115          compsl[byte_off]&=(0xff^bit_off);
116        else compsl[byte_off]|=bit_off;
117        bit_off>>=1;
118        if (!bit_off)
119        { byte_off++; bit_off=128; }
120
121      }
122      memcpy(MK_FP(0xb800,CGAY(y)+x/8),compsl,(w+7)/8);
123    }
124    else
125    {
126      sp=(long)(((long) y*(long)(xres+1)+(long)x)>>16);
127      if (sp!=ls)
128      {
129        outportb(0x3c4,14);
130        outportb(0x3c5,(sp)^2);
131        ls=sp;
132      }
133      off=(((long)y*(long)(xres+1)+(long)x)&(long)0xffff);
134
135
136
137      for (i=0;i<w;i++)
138      {
139        pokeb(0xa000,off&0xffff,sl[i]);
140        if (off>=0xffff)
141        { off=0;
142          sp++;
143          outportb(0x3c4,14);
144          outportb(0x3c5,(sp)^2);
145        }
146        else
147          off++;
148      }
149    }
150    y++;
151  }
152}
153
154void update_dirty(image *im, int xoff, int yoff)
155{
156
157  int count,x1,y1,x2,y2;
158  dirty_rect *dr,*q;
159  image *Xim;
160#ifdef DIRECT_SCREEN
161  if (im!=screen || vmode!=19)
162  {
163#endif
164  CHECK(im->special);  // make sure the image has the ablity to contain dirty areas
165  if (im->special->keep_dirt==0)
166    put_image(im,xoff,yoff);
167  else
168  {
169    count=im->special->dirties.number_nodes();
170    if (!count) return;  // if nothing to update, return
171    (linked_node *) dr=im->special->dirties.first();
172    while (count>0)
173    {
174      x1=dr->dx1;               // update this area for this dirty rectangle
175      y1=dr->dy1;
176      x2=dr->dx2;
177      y2=dr->dy2;
178
179  int dt_matrix[]={0,  136,24, 170,
180                   68, 204,102,238,
181                   51, 187, 17,153,
182                   119,255, 85,221};
183
184
185      int ls,iy,i;
186      unsigned int sp;
187      long off;
188      char *sl;
189      ls=-1;
190      iy=y1;
191      while (iy<=y2)
192      {
193        sl=im->scan_line(iy);
194        if (vmode!=19 && vmode!=CGA_640x200x2)
195        {
196          sp=(long)(((long) (iy+yoff)*(long)(xres+1)+(long)x1+xoff)>>16);
197          if (sp!=ls)
198          {
199            outportb(0x3c4,14);
200            outportb(0x3c5,(sp)^2);
201            ls=sp;
202          }
203          off=(((long)(iy+yoff)*(long)(xres+1)+(long)x1+xoff)&(long)0xffff);
204          for (i=x1;i<=x2;i++)
205          {
206            pokeb(0xa000,off&0xffff,sl[i]);
207            if (off>=0xffff)
208            { off=0;
209              sp++;
210              outportb(0x3c4,14);
211              outportb(0x3c5,(sp)^2);
212            }
213            else
214              off++;
215          }
216        }
217        else if (vmode!=CGA_640x200x2)
218          memcpy(MK_FP(0xa000,(iy+yoff)*320+x1),&sl[x1+xoff],(x2-x1+1));
219        else
220        {
221          int byte_off,bit_off,w;
222          char compsl[80];
223          byte_off=0;
224          memcpy(compsl,MK_FP(0xb800,CGAY((iy+yoff))+(x1+xoff)/8),(x2+xoff)/8-(x1+xoff)/8+1);
225          bit_off=128>>((x1+xoff)%8);
226          for (i=(x1+xoff);i<=(x2+xoff);i++)
227          {
228            if (last_loaded()->red(sl[i])>dt_matrix[i%4+((iy+yoff)%4)*4])
229              compsl[byte_off]&=(0xff^bit_off);
230            else
231              compsl[byte_off]|=bit_off;
232            bit_off>>=1;
233            if (!bit_off)
234            { byte_off++;
235              bit_off=128;
236            }
237
238          }
239          memcpy(MK_FP(0xb800,CGAY((iy+yoff))+(x1+xoff)/8),compsl,(xoff+x2)/8-(x1+xoff)/8+1);
240        }
241        iy++;
242
243      }
244      q=dr;
245      (linked_node *)dr=dr->next();
246      im->special->dirties.unlink((linked_node *)q);
247      delete q;
248      count--;
249    }
250  }
251#ifdef DIRECT_SCREEN
252  }
253#endif
254}
255
256extern palette *lastl;
257
258void palette::load()
259{
260  if (lastl)
261    delete lastl;
262  lastl=copy();
263  unsigned s,o;
264  if (get_vmode()!=CGA_640x200x2)
265  {
266    s=FP_SEG(pal); o=FP_OFF(pal);
267    asm {
268    mov ax, o
269    mov si, ax
270    push ds
271    mov ax, s
272    mov ds, ax
273    mov cx, 128
274    mov dx, 986
275    }
276retrace_start :
277    asm {
278    in al,dx
279    test al, 8
280    jnz retrace_start
281    }
282vert_retrace :
283    asm {
284    in al, dx
285    test al,8
286    jz vert_retrace
287    xor al,al
288    mov dx, 968
289    out dx, al
290    mov dx, 969
291    cld
292    }
293load_again :
294    asm {
295    lodsb
296    shr al,1
297    shr al,1
298    out dx,al             //     ; {three bytes per color}
299    jmp jadr1
300    }
301jadr1 :
302    asm {
303    lodsb
304    shr al,1
305    shr al,1
306    out dx,al
307    jmp jadr2 :
308    }
309jadr2 :
310    asm {
311    lodsb
312    shr al,1
313    shr al,1
314    out dx,al
315    jmp jadr3
316    }
317jadr3 :
318    asm {
319    loop load_again
320    mov dx, 986
321    }
322retrace_start2 :
323    asm {
324    in al,dx
325    test al, 8
326    jnz retrace_start2
327    }
328vert_retrace2 :
329    asm {
330    in al, dx
331    test al,8
332    jz vert_retrace2
333    xor al,al
334    mov dx, 968
335    out dx, al
336    mov dx, 969
337    mov cx,128
338    mov al, 128
339    mov dx, 968
340    out dx, al
341    mov dx, 969
342  }
343load_again2 :
344  asm {
345    lodsb
346    shr al,1
347    shr al,1
348     out dx,al
349    lodsb
350    shr al,1
351    shr al,1
352    out dx,al
353    lodsb
354    shr al,1
355    shr al,1
356    out dx,al
357    loop load_again2
358    pop ds
359    }
360  }
361  else lastl->black_white();
362  current_background=bg;
363}
364
365void palette::load_nice()
366{ load(); }
367
Note: See TracBrowser for help on using the repository browser.