fixed: broken fs0, sram saves
[fceu.git] / drivers / cli / dos-video.c
CommitLineData
63bd5be0 1/* FCE Ultra - NES/Famicom Emulator\r
2 *\r
3 * Copyright notice for this file:\r
4 * Copyright (C) 1998 \Firebug\\r
5 * Copyright (C) 2002 Ben Parnell\r
6 *\r
7 * This program is free software; you can redistribute it and/or modify\r
8 * it under the terms of the GNU General Public License as published by\r
9 * the Free Software Foundation; either version 2 of the License, or\r
10 * (at your option) any later version.\r
11 *\r
12 * This program is distributed in the hope that it will be useful,\r
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
15 * GNU General Public License for more details.\r
16 *\r
17 * You should have received a copy of the GNU General Public License\r
18 * along with this program; if not, write to the Free Software\r
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
20 */\r
21\r
22#include <stdio.h>\r
23#include <string.h>\r
24#include <dpmi.h>\r
25#include <sys/farptr.h>\r
26#include <go32.h>\r
27#include <pc.h>\r
28\r
29#include "dos.h"\r
30#include "dos-video.h"\r
31\r
32#define TEXT 3\r
33#define G320x200x256 0x13\r
34\r
35static void vga_waitretrace(void)\r
36{ \r
37 while(inp(0x3da)&0x8); \r
38 while(!(inp(0x3da)&0x8));\r
39}\r
40\r
41static void vga_setmode(int mode)\r
42{\r
43 __dpmi_regs regs;\r
44\r
45 memset(&regs,0,sizeof(regs));\r
46 regs.x.ax=mode;\r
47\r
48 __dpmi_int(0x10,&regs);\r
49}\r
50\r
51void vga_setpalette(int i, int r, int g, int b)\r
52{ \r
53 outp(0x3c8,i);\r
54 outp(0x3c9,r);\r
55 outp(0x3c9,g);\r
56 outp(0x3c9,b); \r
57}\r
58\r
59int FCEUDvmode=1;\r
60\r
61static int vidready=0;\r
62\r
63/* Part of the VGA low-level mass register setting code derived from\r
64 code by \Firebug\.\r
65*/\r
66\r
67#include "vgatweak.c"\r
68\r
69void SetBorder(void)\r
70{\r
71 inportb(0x3da);\r
72 outportb(0x3c0,(0x11|0x20));\r
73 outportb(0x3c0,0x80);\r
74}\r
75\r
76void TweakVGA(int VGAMode)\r
77{\r
78 int I;\r
79 \r
80 vga_waitretrace();\r
81\r
82 outportb(0x3C8,0x00);\r
83 for(I=0;I<768;I++) outportb(0x3C9,0x00);\r
84\r
85 outportb(0x3D4,0x11);\r
86 I=inportb(0x3D5)&0x7F;\r
87 outportb(0x3D4,0x11);\r
88 outportb(0x3D5,I);\r
89\r
90 switch(VGAMode)\r
91 {\r
92 case 1: for(I=0;I<25;I++) VGAPortSet(v256x240[I]);break;\r
93 case 2: for(I=0;I<25;I++) VGAPortSet(v256x256[I]);break;\r
94 case 3: for(I=0;I<25;I++) VGAPortSet(v256x256S[I]);break;\r
95 case 6: for(I=0;I<25;I++) VGAPortSet(v256x224S[I]);break;\r
96 case 8: for(I=0;I<25;I++) VGAPortSet(v256x224_103[I]);break;\r
97 default: break;\r
98 }\r
99\r
100 outportb(0x3da,0);\r
101}\r
102\r
103\r
104static uint8 palettedbr[256],palettedbg[256],palettedbb[256];\r
105\r
106static void FlushPalette(void)\r
107{\r
108 int x;\r
109 for(x=0;x<256;x++)\r
110 {\r
111 int z=x;\r
112 vga_setpalette(z,palettedbr[x]>>2,palettedbg[x]>>2,palettedbb[x]>>2);\r
113 }\r
114}\r
115\r
116void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)\r
117{\r
118 palettedbr[index]=r;\r
119 palettedbg[index]=g;\r
120 palettedbb[index]=b;\r
121 if(vidready)\r
122 {\r
123 vga_setpalette(index,r>>2,g>>2,b>>2);\r
124 }\r
125}\r
126\r
127\r
128void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)\r
129{\r
130 *r=palettedbr[i];\r
131 *g=palettedbg[i];\r
132 *b=palettedbb[i];\r
133}\r
134\r
135static uint32 ScreenLoc;\r
136\r
137int InitVideo(void)\r
138{\r
139 vidready=0;\r
140 switch(FCEUDvmode)\r
141 {\r
142 default:\r
143 case 1:\r
144 case 2:\r
145 case 3:\r
146 case 6:\r
147 case 8:\r
148 vga_setmode(G320x200x256);\r
149 vidready|=1;\r
150 ScreenLoc=0xa0000;\r
151 TweakVGA(FCEUDvmode);\r
152 SetBorder();\r
153 DOSMemSet(ScreenLoc, 128, 256*256);\r
154 break;\r
155 }\r
156 vidready|=2;\r
157 FlushPalette();\r
158 return 1;\r
159}\r
160\r
161void KillVideo(void)\r
162{\r
163 if(vidready)\r
164 {\r
165 vga_setmode(TEXT);\r
166 vidready=0;\r
167 }\r
168}\r
169void LockConsole(void){}\r
170void UnlockConsole(void){}\r
171void BlitScreen(uint8 *XBuf)\r
172{\r
173 uint32 dest;\r
174 int tlines;\r
175\r
176 if(eoptions&4 && !NoWaiting)\r
177 vga_waitretrace();\r
178\r
179 tlines=erendline-srendline+1;\r
180\r
181 dest=ScreenLoc;\r
182\r
183 switch(FCEUDvmode)\r
184 {\r
185 case 1:dest+=(((240-tlines)>>1)<<8);break;\r
186 case 2:\r
187 case 3:dest+=(((256-tlines)>>1)<<8);break;\r
188 case 4:\r
189 case 5:dest+=(((240-tlines)>>1)*640+((640-512)>>1));break;\r
190 case 8:\r
191 case 6:if(tlines>224) tlines=224;dest+=(((224-tlines)>>1)<<8);break;\r
192 }\r
193 \r
194 XBuf+=(srendline<<8)+(srendline<<4);\r
195 \r
196 _farsetsel(_dos_ds);\r
197 if(eoptions&DO_CLIPSIDES)\r
198 {\r
199 asm volatile( \r
200 "agoop1:\n\t"\r
201 "movl $30,%%eax\n\t"\r
202 "agoop2:\n\t"\r
203 "movl (%%esi),%%edx\n\t"\r
204 "movl 4(%%esi),%%ecx\n\t"\r
205 ".byte 0x64 \n\t"\r
206 "movl %%edx,(%%edi)\n\t"\r
207 ".byte 0x64 \n\t"\r
208 "movl %%ecx,4(%%edi)\n\t"\r
209 "addl $8,%%esi\n\t"\r
210 "addl $8,%%edi\n\t"\r
211 "decl %%eax\n\t"\r
212 "jne agoop2\n\t"\r
213 "addl $32,%%esi\n\t"\r
214 "addl $16,%%edi\n\t"\r
215 "decb %%bl\n\t"\r
216 "jne agoop1\n\t"\r
217 :\r
218 : "S" (XBuf+8), "D" (dest+8), "b" (tlines)\r
219 : "%eax","%cc","%edx","%ecx" );\r
220 }\r
221 else\r
222 {\r
223 asm volatile( \r
224 "goop1:\n\t"\r
225 "movl $32,%%eax\n\t"\r
226 "goop2:\n\t"\r
227 "movl (%%esi),%%edx\n\t"\r
228 "movl 4(%%esi),%%ecx\n\t"\r
229 ".byte 0x64 \n\t"\r
230 "movl %%edx,(%%edi)\n\t"\r
231 ".byte 0x64 \n\t"\r
232 "movl %%ecx,4(%%edi)\n\t"\r
233 "addl $8,%%esi\n\t"\r
234 "addl $8,%%edi\n\t"\r
235 "decl %%eax\n\t"\r
236 "jne goop2\n\t"\r
237 "addl $16,%%esi\n\t"\r
238 "decb %%bl\n\t"\r
239 "jne goop1\n\t"\r
240 :\r
241 : "S" (XBuf), "D" (dest), "b" (tlines)\r
242 : "%eax","%cc","%edx","%ecx" );\r
243 }\r
244}\r
245\r
246\r