|
|
1.1 root 1: /*
2: Hatari
3:
4: VDI (Virtual Device Interface) (Trap #2)
5:
6: To get higher resolutions on the Desktop, we intercept the VDI/Line-A calls and set elements
7: in their structures to the higher width/height/cel/planes. We need to intercept the initial Line-A
8: call(which we force into the TOS on boot-up) and also the init calls to the VDI.
9: As we intercept the VDI calls, this is a good point to pass them on to the accelerated native
10: PC functions if we need to - this improves drawing speed far greater than any ST software
11: accelerator.
12: */
13:
14: #include "main.h"
15: #include "decode.h"
16: /*#include "dialog.h"*/
17: #include "file.h"
18: #include "gemdos.h"
19: #include "m68000.h"
20: #include "memAlloc.h"
21: #include "screen.h"
22: #include "stMemory.h"
23: #include "vdi.h"
24: #include "video.h"
25:
26:
27: enum { /* Taken from dialogtosgem.h - Thothy */
28: GEMRES_640x480,
29: GEMRES_800x600,
30: GEMRES_1024x768
31: };
32:
33: enum {
34: GEMCOLOUR_2,
35: GEMCOLOUR_4,
36: GEMCOLOUR_16
37: };
38:
39:
40: BOOL bUseVDIRes=FALSE; // Set to TRUE(if want VDI), or FALSE(ie for games)
41: BOOL bHoldScreenDisplay=TRUE; // Hold display until initialised VDI(prevents TOS >2.05 showing ATARI logo)
42: int LineABase; // Line-A structure
43: int FontBase; // Font base, used for 16-pixel high font
44: unsigned int VDI_OldPC; // When call Trap#2, store off PC
45:
46: int VDIWidth=640,VDIHeight=480; // 640x480,800x600 or 1024x768
47: int VDIRes=0; // 0,1 or 2(low, medium, high)
48: int VDIPlanes=4,VDIColours=16,VDICharHeight=8; // To match VDIRes
49:
50: unsigned long Control;
51: unsigned long Intin;
52: unsigned long Ptsin;
53: unsigned long Intout;
54: unsigned long Ptsout;
55:
56: //-----------------------------------------------------------------------
57: // Desktop TOS 1.04 and TOS 2.06 desktop configuration files
58: unsigned char DesktopScript[504] = {
59: 0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
60: 0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
61: 0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
62: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
63: 0x23,0x45,0x20,0x31,0x38,0x20,0x31,0x31,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,
64: 0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x32,0x20,0x30,0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,
65: 0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,
66: 0x30,0x20,0x30,0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,
67: 0x30,0x30,0x20,0x46,0x46,0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
68: 0x30,0x30,0x20,0x46,0x46,0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,
69: 0x31,0x20,0x30,0x30,0x20,0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,
70: 0x20,0x30,0x33,0x20,0x30,0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,0x48,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x46,0x46,0x20,0x30,0x34,0x20,
71: 0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,0x20,0x30,0x31,0x20,0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,
72: 0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x41,0x50,0x50,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,
73: 0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x54,0x54,0x50,0x40,0x20,0x40,0x20,0x0D,
74: 0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,0x20,0x20,0x20,0x2A,0x2E,0x54,0x4F,0x53,0x40,0x20,0x40,0x20,0x0D,0x0A,0x1A,
75: };
76:
77: unsigned char NewDeskScript[786] = {
78: 0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
79: 0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
80: 0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
81: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
82: 0x23,0x4B,0x20,0x34,0x46,0x20,0x35,0x33,0x20,0x34,0x43,0x20,0x30,0x30,0x20,0x34,0x36,0x20,0x34,0x32,0x20,0x34,0x33,0x20,0x35,0x37,0x20,0x34,0x35,0x20,0x35,0x38,
83: 0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,
84: 0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x35,0x32,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x34,0x44,0x20,0x35,0x36,0x20,0x35,0x30,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
85: 0x23,0x45,0x20,0x31,0x38,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x36,0x20,0x0D,0x0A,0x23,0x51,0x20,0x34,0x31,0x20,0x34,0x30,0x20,0x34,0x33,0x20,0x34,0x30,0x20,
86: 0x34,0x33,0x20,0x34,0x30,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,
87: 0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x32,0x20,0x30,0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,
88: 0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,
89: 0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x34,0x20,
90: 0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x43,0x20,0x30,0x42,0x20,0x32,0x36,
91: 0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x38,0x20,0x30,0x46,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,
92: 0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x36,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
93: 0x23,0x4E,0x20,0x46,0x46,0x20,0x30,0x34,0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,0x20,0x30,0x31,
94: 0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x41,
95: 0x50,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,
96: 0x40,0x20,0x0D,0x0A,0x23,0x59,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x47,0x54,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,
97: 0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x54,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,
98: 0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x4F,0x53,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x46,0x46,
99: 0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x46,0x46,
100: 0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
101: 0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,0x20,0x30,0x33,0x20,0x30,
102: 0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,0x48,0x40,0x20,0x40,0x20,0x0D,0x0A,
103: };
104:
105: //-----------------------------------------------------------------------
106: /*
107: Set Width/Height/BitDepth according to passed GEMRES_640x480, GEMRES_800x600 or GEMRES_1024x768
108: */
109: void VDI_SetResolution(int GEMRes,int GEMColour)
110: {
111: // Resolution
112: switch(GEMRes) {
113: case GEMRES_640x480:
114: VDIWidth = 640;
115: VDIHeight = 480;
116: break;
117: case GEMRES_800x600:
118: VDIWidth = 800;
119: VDIHeight = 600;
120: break;
121: case GEMRES_1024x768:
122: VDIWidth = 1024;
123: VDIHeight = 768;
124: break;
125: }
126:
127: // Colour depth
128: switch(GEMColour) {
129: case GEMCOLOUR_2:
130: VDIRes = 2;
131: VDIPlanes = 1;
132: VDIColours = 2;
133: VDICharHeight = 16;
134: break;
135: case GEMCOLOUR_4:
136: VDIRes = 1;
137: VDIPlanes = 2;
138: VDIColours = 4;
139: VDICharHeight = 8;
140: break;
141: case GEMCOLOUR_16:
142: VDIRes = 0;
143: VDIPlanes = 4;
144: VDIColours = 16;
145: VDICharHeight = 8;
146: break;
147: }
148:
149: // Force screen code to re-set bitmap/full-screen
150: Screen_SetDrawModes();
151: Screen_SetupRGBTable(bInFullScreen);
152: Screen_SetFullUpdate();
153: PrevSTRes = -1;
154:
155: // Write resolution to re-boot takes effect with correct bit-depth
156: VDI_FixDesktopInf();
157: }
158:
159: //-----------------------------------------------------------------------
160: /*
161: Check VDI call and see if we need to re-direct to our own routines
162: Return TRUE if we've handled the exception, else return FALSE
163:
164: We enter here with Trap #2, so D1 is pointer to VDI vectors, ie Control, Intin, Ptsin etc...
165: */
166: BOOL VDI(void)
167: {
168: unsigned long TablePtr = Regs[REG_D1];
169: // unsigned short int OpCode;
170:
171: // Read off table pointers
172: Control = STMemory_ReadLong(TablePtr);
173: Intin = STMemory_ReadLong(TablePtr+4);
174: Ptsin = STMemory_ReadLong(TablePtr+8);
175: Intout = STMemory_ReadLong(TablePtr+12);
176: Ptsout = STMemory_ReadLong(TablePtr+16);
177:
178: // OpCode = STMemory_ReadWord(Control);
179: // Check OpCode
180: // 8 - Text Font
181: // if (OpCode==9) {
182: // return(TRUE);
183: // }
184:
185: // Call as normal!
186: return(FALSE);
187: }
188:
189: //-----------------------------------------------------------------------
190: /*
191: Modify Line-A structure for our VDI resolutions
192: */
193: void VDI_LineA(void)
194: {
195: if (bUseVDIRes) {
196: STMemory_WriteWord(LineABase-6*2,VDIWidth); // v_rez_hz
197: STMemory_WriteWord(LineABase-2*2,VDIHeight); // v_rez_vt
198: STMemory_WriteWord(LineABase-1*2,(VDIWidth*VDIPlanes)/8); // bytes_lin
199: STMemory_WriteWord(LineABase+1*2,(VDIWidth*VDIPlanes)/8); // width
200:
201: STMemory_WriteWord(LineABase-23*2,VDICharHeight); // char height
202: STMemory_WriteWord(LineABase-22*2,(VDIWidth/8)-1); // v_cel_mx
203: STMemory_WriteWord(LineABase-21*2,(VDIHeight/VDICharHeight)-1); // v_cel_my
204: STMemory_WriteWord(LineABase-20*2,VDICharHeight*((VDIWidth*VDIPlanes)/8)); // v_cel_wr
205:
206: STMemory_WriteWord(LineABase-0*2,VDIPlanes); // planes
207: }
208: }
209:
210: //-----------------------------------------------------------------------
211: /*
212: This is called on completion of a VDI Trap, used to modify return structure for
213: */
214: void VDI_Complete(void)
215: {
216: unsigned short int OpCode;
217:
218: OpCode = STMemory_ReadWord(Control);
219: // Is 'Open Workstation', or 'Open Virtual Screen Workstation'?
220: if ( (OpCode==1) || (OpCode==100) ) {
221: STMemory_WriteWord(Intout,VDIWidth-1); // IntOut[0] Width-1
222: STMemory_WriteWord(Intout+1*2,VDIHeight-1); // IntOut[1] Height-1
223: STMemory_WriteWord(Intout+13*2,VDIColours); // IntOut[13] #colours
224: STMemory_WriteWord(Intout+39*2,512); // IntOut[39] #available colours
225:
226: STMemory_WriteWord(LineABase-0x15a*2,VDIWidth-1); // WKXRez
227: STMemory_WriteWord(LineABase-0x159*2,VDIHeight-1); // WKYRez
228:
229: VDI_LineA(); // And modify Line-A structure accordingly
230:
231: // Show screen(used to hide boot-up sequence in TOS >2.06)
232: bHoldScreenDisplay = FALSE;
233: }
234: }
235:
236: //-----------------------------------------------------------------------
237: /*
238: This is called after completion of each VDI call
239: */
240: void VDI_OpCode(void)
241: {
242: VDI_Complete();
243:
244: /* Set PC back to where originated from to continue instruction decoding */
245: //FIXME PC = VDI_OldPC;
246:
247: // RET
248: }
249:
250: //-----------------------------------------------------------------------
251: /*
252: Save desktop configuration file for VDI, eg desktop.inf(TOS 1.04) or newdesk.inf(TOS 2.06)
253: */
254: void VDI_SaveDesktopInf(char *pszFileName,unsigned char *Script,long ScriptSize)
255: {
256: // Just save file
257: File_Save(/*NULL,*/pszFileName,Script,ScriptSize,FALSE);
258: }
259:
260: //-----------------------------------------------------------------------
261: /*
262: Modify exisiting ST desktop configuration files to set resolution(keep user settings)
263: */
264: void VDI_ModifyDesktopInf(char *pszFileName)
265: {
266: long InfSize;
267: unsigned char *pInfData;
268: int i;
269:
270: // Load our '.inf' file
271: pInfData = (unsigned char *)File_Read(pszFileName,NULL,&InfSize,NULL);
272: if (pInfData) {
273: // Scan file for '#E'
274: i = 0;
275: while(i<(InfSize-8)) {
276: if ( (pInfData[i]=='#') && (pInfData[i+1]=='E') ) {
277: // Modify resolution
278: pInfData[i+7] = '1'+VDIRes;
279: goto done_modify;
280: }
281:
282: i++;
283: }
284:
285: done_modify:;
286: /* And save */
287: File_Save(/*NULL,*/pszFileName,pInfData,InfSize,FALSE);
288: /* Free */
289: Memory_Free(pInfData);
290: }
291: }
292:
293: //-----------------------------------------------------------------------
294: /*
295: Modify(or create) ST desktop configuration files so VDI boots up in correct colour depth
296: */
297: void VDI_FixDesktopInf(void)
298: {
299: char szDesktopFileName[MAX_FILENAME_LENGTH],szNewDeskFileName[MAX_FILENAME_LENGTH];
300:
301: /* Create filenames for hard-drive */
302: GemDOS_CreateHardDriveFileName(2,"/desktop.inf",szDesktopFileName);
303: GemDOS_CreateHardDriveFileName(2,"/newdesk.inf",szNewDeskFileName);
304:
305: /* First, check if files exist(ie modify or replace) */
306: if (!File_Exists(szDesktopFileName))
307: VDI_SaveDesktopInf(szDesktopFileName,DesktopScript,sizeof(DesktopScript));
308: VDI_ModifyDesktopInf(szDesktopFileName);
309:
310: if (!File_Exists(szNewDeskFileName))
311: VDI_SaveDesktopInf(szNewDeskFileName,NewDeskScript,sizeof(NewDeskScript));
312: VDI_ModifyDesktopInf(szNewDeskFileName);
313: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.