|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari - vdi.c
3:
1.1.1.16! root 4: This file is distributed under the GNU General Public License, version 2
! 5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: VDI (Virtual Device Interface) (Trap #2)
8:
1.1.1.5 root 9: To get higher resolutions on the Desktop, we intercept the VDI/Line-A calls
10: and set elements in their structures to the higher width/height/cel/planes.
11: We need to intercept the initial Line-A call (which we force into the TOS on
12: boot-up) and also the init calls to the VDI.
1.1 root 13: */
1.1.1.12 root 14: const char VDI_fileid[] = "Hatari vdi.c : " __DATE__ " " __TIME__;
1.1 root 15:
16: #include "main.h"
17: #include "file.h"
18: #include "gemdos.h"
19: #include "m68000.h"
20: #include "screen.h"
21: #include "stMemory.h"
22: #include "vdi.h"
23: #include "video.h"
1.1.1.9 root 24: #include "configuration.h"
1.1 root 25:
26:
1.1.1.7 root 27: Uint32 VDI_OldPC; /* When call Trap#2, store off PC */
1.1.1.2 root 28:
1.1.1.14 root 29: bool bVdiAesIntercept = false; /* Set to true to trace VDI & AES calls */
1.1.1.12 root 30: bool bUseVDIRes = false; /* Set to true (if want VDI), or false (ie for games) */
1.1.1.9 root 31: /* defaults */
32: int VDIRes = 0; /* 0,1 or 2 (low, medium, high) */
33: int VDIWidth = 640; /* 640x480, 800x600 or 1024x768 */
34: int VDIHeight = 480;
35: int VDIPlanes = 4;
36:
37: static Uint32 LineABase; /* Line-A structure */
38: static Uint32 FontBase; /* Font base, used for 16-pixel high font */
1.1 root 39:
1.1.1.14 root 40: /* Last VDI opcode & vectors */
41: static Uint16 VDIOpCode;
42: static Uint32 VDIControl;
43: static Uint32 VDIIntin;
44: static Uint32 VDIPtsin;
45: static Uint32 VDIIntout;
46: static Uint32 VDIPtsout;
47: #if ENABLE_TRACING
48: /* Last AES opcode & vectors */
49: static Uint32 AESControl;
50: static Uint32 AESGlobal;
51: static Uint32 AESIntin;
52: static Uint32 AESIntout;
53: static Uint32 AESAddrin;
54: static Uint32 AESAddrout;
55: static Uint16 AESOpCode;
56: #endif
1.1 root 57:
1.1.1.2 root 58:
59: /*-----------------------------------------------------------------------*/
60: /* Desktop TOS 1.04 and TOS 2.06 desktop configuration files */
1.1.1.8 root 61: static const Uint8 DesktopScript[504] =
1.1.1.3 root 62: {
1.1.1.9 root 63: 0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,
64: 0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
65: 0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,
66: 0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
67: 0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,
68: 0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
69: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
70: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
71: 0x23,0x45,0x20,0x31,0x38,0x20,0x31,0x31,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,
72: 0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,
73: 0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,
74: 0x32,0x20,0x30,0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,
75: 0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,
76: 0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,
77: 0x30,0x20,0x30,0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,
78: 0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,
79: 0x30,0x30,0x20,0x46,0x46,0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,
80: 0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
81: 0x30,0x30,0x20,0x46,0x46,0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,
82: 0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,
83: 0x31,0x20,0x30,0x30,0x20,0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,
84: 0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,
85: 0x20,0x30,0x33,0x20,0x30,0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,
86: 0x48,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x46,0x46,0x20,0x30,0x34,0x20,
87: 0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,
88: 0x20,0x30,0x31,0x20,0x20,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x0D,0x0A,0x23,
89: 0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x41,0x50,0x50,0x40,
90: 0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x20,0x20,
91: 0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,0x20,0x30,0x33,
92: 0x20,0x46,0x46,0x20,0x20,0x20,0x2A,0x2E,0x54,0x54,0x50,0x40,0x20,0x40,0x20,0x0D,
93: 0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,0x20,0x20,0x20,0x2A,0x2E,0x54,0x4F,
94: 0x53,0x40,0x20,0x40,0x20,0x0D,0x0A,0x1A
1.1 root 95: };
96:
1.1.1.8 root 97: static const Uint8 NewDeskScript[786] =
1.1.1.3 root 98: {
1.1.1.9 root 99: 0x23,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,0x23,0x62,0x30,0x30,0x30,0x30,
100: 0x30,0x30,0x0D,0x0A,0x23,0x63,0x37,0x37,0x37,0x30,0x30,0x30,0x37,0x30,0x30,0x30,
101: 0x36,0x30,0x30,0x30,0x37,0x30,0x30,0x35,0x35,0x32,0x30,0x30,0x35,0x30,0x35,0x35,
102: 0x35,0x32,0x32,0x32,0x30,0x37,0x37,0x30,0x35,0x35,0x37,0x30,0x37,0x35,0x30,0x35,
103: 0x35,0x35,0x30,0x37,0x37,0x30,0x33,0x31,0x31,0x31,0x31,0x30,0x33,0x0D,0x0A,0x23,
104: 0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
105: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
106: 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,
107: 0x23,0x4B,0x20,0x34,0x46,0x20,0x35,0x33,0x20,0x34,0x43,0x20,0x30,0x30,0x20,0x34,
108: 0x36,0x20,0x34,0x32,0x20,0x34,0x33,0x20,0x35,0x37,0x20,0x34,0x35,0x20,0x35,0x38,
109: 0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
110: 0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,
111: 0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x35,0x32,0x20,0x30,0x30,0x20,0x30,0x30,
112: 0x20,0x34,0x44,0x20,0x35,0x36,0x20,0x35,0x30,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
113: 0x23,0x45,0x20,0x31,0x38,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x36,0x20,0x0D,
114: 0x0A,0x23,0x51,0x20,0x34,0x31,0x20,0x34,0x30,0x20,0x34,0x33,0x20,0x34,0x30,0x20,
115: 0x34,0x33,0x20,0x34,0x30,0x20,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,
116: 0x20,0x30,0x30,0x20,0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,
117: 0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x32,0x20,0x30,
118: 0x42,0x20,0x32,0x36,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,
119: 0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x41,0x20,0x30,0x46,0x20,0x31,0x41,0x20,
120: 0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,
121: 0x30,0x20,0x30,0x45,0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,
122: 0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x34,0x20,
123: 0x30,0x37,0x20,0x32,0x36,0x20,0x30,0x43,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,
124: 0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x43,0x20,0x30,0x42,0x20,0x32,0x36,
125: 0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,
126: 0x30,0x30,0x20,0x30,0x38,0x20,0x30,0x46,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,
127: 0x30,0x20,0x40,0x0D,0x0A,0x23,0x57,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x36,
128: 0x20,0x30,0x31,0x20,0x31,0x41,0x20,0x30,0x39,0x20,0x30,0x30,0x20,0x40,0x0D,0x0A,
129: 0x23,0x4E,0x20,0x46,0x46,0x20,0x30,0x34,0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,
130: 0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x44,0x20,0x46,0x46,0x20,0x30,0x31,
131: 0x20,0x30,0x30,0x30,0x20,0x40,0x20,0x2A,0x2E,0x2A,0x40,0x20,0x40,0x20,0x0D,0x0A,
132: 0x23,0x47,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x41,
133: 0x50,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x47,0x20,0x30,0x33,0x20,
134: 0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x50,0x52,0x47,0x40,0x20,0x40,0x20,
135: 0x40,0x20,0x0D,0x0A,0x23,0x59,0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,
136: 0x20,0x2A,0x2E,0x47,0x54,0x50,0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x50,
137: 0x20,0x30,0x33,0x20,0x46,0x46,0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x54,0x50,
138: 0x40,0x20,0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x46,0x20,0x30,0x33,0x20,0x30,0x34,
139: 0x20,0x30,0x30,0x30,0x20,0x2A,0x2E,0x54,0x4F,0x53,0x40,0x20,0x40,0x20,0x40,0x20,
140: 0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x46,0x46,
141: 0x20,0x43,0x20,0x48,0x41,0x52,0x44,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,0x40,0x20,
142: 0x0D,0x0A,0x23,0x4D,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x46,0x46,
143: 0x20,0x41,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,0x40,0x20,
144: 0x40,0x20,0x0D,0x0A,0x23,0x4D,0x20,0x30,0x31,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
145: 0x46,0x46,0x20,0x42,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x44,0x49,0x53,0x4B,
146: 0x40,0x20,0x40,0x20,0x0D,0x0A,0x23,0x54,0x20,0x30,0x30,0x20,0x30,0x33,0x20,0x30,
147: 0x32,0x20,0x46,0x46,0x20,0x20,0x20,0x54,0x52,0x41,0x53,0x48,0x40,0x20,0x40,0x20,
148: 0x0D,0x0A
1.1 root 149: };
150:
1.1.1.14 root 151: static void VDI_FixDesktopInf(void);
152:
1.1.1.2 root 153:
154: /*-----------------------------------------------------------------------*/
1.1.1.9 root 155: /**
1.1.1.15 root 156: * Called to reset VDI variables on reset.
157: */
158: void VDI_Reset(void)
159: {
160: /* no VDI calls in progress */
161: VDI_OldPC = 0;
162: }
163:
164: /*-----------------------------------------------------------------------*/
165: /**
1.1.1.9 root 166: * Returns given value after constraining it within "min" and "max" values
167: * and making it evenly divisable by "align"
168: */
169: int VDI_Limit(int value, int align, int min, int max)
1.1 root 170: {
1.1.1.9 root 171: value = (value/align)*align;
172: if (value > max)
173: {
174: /* align down */
175: return (max/align)*align;
176: }
177: if (value < min)
178: {
179: /* align up */
180: min += align-1;
181: return (min/align)*align;
182: }
183: return value;
1.1 root 184: }
185:
1.1.1.16! root 186: /*-----------------------------------------------------------------------*/
! 187: /**
! 188: * Limit width and height to VDI screen size in bytes, retaining their ratio.
! 189: * Return true if limiting was done.
! 190: */
! 191: static bool VDI_ByteLimit(int *width, int *height, int planes)
! 192: {
! 193: double ratio;
! 194: int size;
! 195:
! 196: size = (*width)*(*height)*planes/8;
! 197: if (size <= MAX_VDI_BYTES)
! 198: return false;
! 199:
! 200: ratio = sqrt(MAX_VDI_BYTES) / sqrt(size);
! 201: *width = (*width) * ratio;
! 202: *height = (*height) * ratio;
! 203: if (*width < MIN_VDI_WIDTH || *height < MIN_VDI_HEIGHT)
! 204: {
! 205: *width = MIN_VDI_WIDTH;
! 206: *height = MIN_VDI_HEIGHT;
! 207: fputs("Bad VDI screen ratio / too small size -> use smallest valid size.\n", stderr);
! 208: }
! 209: return true;
! 210: }
1.1.1.2 root 211:
212: /*-----------------------------------------------------------------------*/
1.1.1.9 root 213: /**
1.1.1.16! root 214: * Set Width/Height/BitDepth according to passed GEMCOLOR_2/4/16.
! 215: * Align size when necessary.
1.1.1.9 root 216: */
217: void VDI_SetResolution(int GEMColor, int WidthRequest, int HeightRequest)
218: {
1.1.1.16! root 219: int w = WidthRequest;
! 220: int h = HeightRequest;
! 221:
1.1.1.9 root 222: /* Color depth */
223: switch (GEMColor)
224: {
225: case GEMCOLOR_2:
226: VDIRes = 2;
227: VDIPlanes = 1;
228: break;
229: case GEMCOLOR_4:
230: VDIRes = 1;
231: VDIPlanes = 2;
232: break;
233: case GEMCOLOR_16:
234: VDIRes = 0;
235: VDIPlanes = 4;
236: break;
237: }
1.1.1.16! root 238: /* screen size in bytes needs to be below limit */
! 239: VDI_ByteLimit(&w, &h, VDIPlanes);
1.1.1.9 root 240:
241: /* width needs to be aligned to 16 bytes */
1.1.1.16! root 242: VDIWidth = VDI_Limit(w, 128/VDIPlanes, MIN_VDI_WIDTH, MAX_VDI_WIDTH);
! 243: /* height needs to be multiple of cell height (either 8 or 16) */
! 244: VDIHeight = VDI_Limit(h, 16, MIN_VDI_HEIGHT, MAX_VDI_HEIGHT);
! 245:
! 246: printf("VDI screen: request = %dx%d@%d, result = %dx%d@%d\n",
1.1.1.9 root 247: WidthRequest, HeightRequest, VDIPlanes, VDIWidth, VDIHeight, VDIPlanes);
248:
249: /* Write resolution to re-boot takes effect with correct bit-depth */
250: VDI_FixDesktopInf();
251: }
252:
1.1 root 253:
1.1.1.14 root 254: #if ENABLE_TRACING
255:
1.1.1.9 root 256: /*-----------------------------------------------------------------------*/
1.1.1.14 root 257:
1.1.1.16! root 258: /* AES opcodes which have string args */
! 259: static const struct {
! 260: int code; /* AES opcode */
! 261: int count; /* number of char * args _first_ in addrin[] */
! 262: } AESStrings[] = {
! 263: { 0x0D, 1 }, /* appl_find() */
! 264: { 0x12, 1 }, /* appl_search() */
! 265: { 0x23, 1 }, /* menu_register() */
! 266: { 0x34, 1 }, /* form_alert() */
! 267: { 0x51, 1 }, /* scrp_write() */
! 268: { 0x5A, 2 }, /* fsel_input() */
! 269: { 0x5B, 3 }, /* fsel_exinput() */
! 270: { 0x6E, 1 }, /* rsrc_load() */
! 271: { 0x7C, 1 } /* shell_find() */
! 272: };
! 273:
! 274: /* AES opcode -> function name mapping */
! 275: static const char* AESName_10[] = {
! 276: "appl_init", /* (0x0A) */
! 277: "appl_read", /* (0x0B) */
! 278: "appl_write", /* (0x0C) */
! 279: "appl_find", /* (0x0D) */
! 280: "appl_tplay", /* (0x0E) */
! 281: "appl_trecord", /* (0x0F) */
! 282: NULL, /* (0x10) */
! 283: NULL, /* (0x11) */
! 284: "appl_search", /* (0x12) */
! 285: "appl_exit", /* (0x13) */
! 286: "evnt_keybd", /* (0x14) */
! 287: "evnt_button", /* (0x15) */
! 288: "evnt_mesag", /* (0x16) */
! 289: "evnt_mesag", /* (0x17) */
! 290: "evnt_timer", /* (0x18) */
! 291: "evnt_multi", /* (0x19) */
! 292: "evnt_dclick", /* (0x1A) */
! 293: NULL, /* (0x1b) */
! 294: NULL, /* (0x1c) */
! 295: NULL, /* (0x1d) */
! 296: "menu_bar", /* (0x1E) */
! 297: "menu_icheck", /* (0x1F) */
! 298: "menu_ienable", /* (0x20) */
! 299: "menu_tnormal", /* (0x21) */
! 300: "menu_text", /* (0x22) */
! 301: "menu_register", /* (0x23) */
! 302: "menu_popup", /* (0x24) */
! 303: "menu_attach", /* (0x25) */
! 304: "menu_istart", /* (0x26) */
! 305: "menu_settings", /* (0x27) */
! 306: "objc_add", /* (0x28) */
! 307: "objc_delete", /* (0x29) */
! 308: "objc_draw", /* (0x2A) */
! 309: "objc_find", /* (0x2B) */
! 310: "objc_offset", /* (0x2C) */
! 311: "objc_order", /* (0x2D) */
! 312: "objc_edit", /* (0x2E) */
! 313: "objc_change", /* (0x2F) */
! 314: "objc_sysvar", /* (0x30) */
! 315: NULL, /* (0x31) */
! 316: "form_do", /* (0x32) */
! 317: "form_dial", /* (0x33) */
! 318: "form_alert", /* (0x34) */
! 319: "form_error", /* (0x35) */
! 320: "form_center", /* (0x36) */
! 321: "form_keybd", /* (0x37) */
! 322: "form_button", /* (0x38) */
! 323: NULL, /* (0x39) */
! 324: NULL, /* (0x3a) */
! 325: NULL, /* (0x3b) */
! 326: NULL, /* (0x3c) */
! 327: NULL, /* (0x3d) */
! 328: NULL, /* (0x3e) */
! 329: NULL, /* (0x3f) */
! 330: NULL, /* (0x40) */
! 331: NULL, /* (0x41) */
! 332: NULL, /* (0x42) */
! 333: NULL, /* (0x43) */
! 334: NULL, /* (0x44) */
! 335: NULL, /* (0x45) */
! 336: "graf_rubberbox", /* (0x46) */
! 337: "graf_dragbox", /* (0x47) */
! 338: "graf_movebox", /* (0x48) */
! 339: "graf_growbox", /* (0x49) */
! 340: "graf_shrinkbox", /* (0x4A) */
! 341: "graf_watchbox", /* (0x4B) */
! 342: "graf_slidebox", /* (0x4C) */
! 343: "graf_handle", /* (0x4D) */
! 344: "graf_mouse", /* (0x4E) */
! 345: "graf_mkstate", /* (0x4F) */
! 346: "scrp_read", /* (0x50) */
! 347: "scrp_write", /* (0x51) */
! 348: NULL, /* (0x52) */
! 349: NULL, /* (0x53) */
! 350: NULL, /* (0x54) */
! 351: NULL, /* (0x55) */
! 352: NULL, /* (0x56) */
! 353: NULL, /* (0x57) */
! 354: NULL, /* (0x58) */
! 355: NULL, /* (0x59) */
! 356: "fsel_input", /* (0x5A) */
! 357: "fsel_exinput", /* (0x5B) */
! 358: NULL, /* (0x5c) */
! 359: NULL, /* (0x5d) */
! 360: NULL, /* (0x5e) */
! 361: NULL, /* (0x5f) */
! 362: NULL, /* (0x60) */
! 363: NULL, /* (0x61) */
! 364: NULL, /* (0x62) */
! 365: NULL, /* (0x63) */
! 366: "wind_create", /* (0x64) */
! 367: "wind_open", /* (0x65) */
! 368: "wind_close", /* (0x66) */
! 369: "wind_delete", /* (0x67) */
! 370: "wind_get", /* (0x68) */
! 371: "wind_set", /* (0x69) */
! 372: "wind_find", /* (0x6A) */
! 373: "wind_update", /* (0x6B) */
! 374: "wind_calc", /* (0x6C) */
! 375: "wind_new", /* (0x6D) */
! 376: "rsrc_load", /* (0x6E) */
! 377: "rsrc_free", /* (0x6F) */
! 378: "rsrc_gaddr", /* (0x70) */
! 379: "rsrc_saddr", /* (0x71) */
! 380: "rsrc_obfix", /* (0x72) */
! 381: "rsrc_rcfix", /* (0x73) */
! 382: NULL, /* (0x74) */
! 383: NULL, /* (0x75) */
! 384: NULL, /* (0x76) */
! 385: NULL, /* (0x77) */
! 386: "shel_read", /* (0x78) */
! 387: "shel_write", /* (0x79) */
! 388: "shel_get", /* (0x7A) */
! 389: "shel_put", /* (0x7B) */
! 390: "shel_find", /* (0x7C) */
! 391: "shel_envrn", /* (0x7D) */
! 392: NULL, /* (0x7e) */
! 393: NULL, /* (0x7f) */
! 394: NULL, /* (0x80) */
! 395: NULL, /* (0x81) */
! 396: "appl_getinfo" /* (0x82) */
! 397: };
! 398:
1.1.1.9 root 399: /**
1.1.1.14 root 400: * Map AES call opcode to an AES function name
1.1.1.9 root 401: */
1.1.1.14 root 402: static const char* AES_Opcode2Name(Uint16 opcode)
1.1 root 403: {
1.1.1.16! root 404: int code = opcode - 10;
! 405: if (code >= 0 && code < ARRAYSIZE(AESName_10) && AESName_10[code])
! 406: return AESName_10[code];
1.1.1.14 root 407: else
408: return "???";
1.1 root 409: }
410:
1.1.1.9 root 411: /**
1.1.1.16! root 412: * Output AES call info, including some of args
! 413: */
! 414: static void AES_OpcodeInfo(FILE *fp, Uint16 opcode)
! 415: {
! 416: int code = opcode - 10;
! 417: fprintf(fp, "AES call %3hd ", opcode);
! 418: if (code >= 0 && code < ARRAYSIZE(AESName_10) && AESName_10[code])
! 419: {
! 420: bool first = true;
! 421: int i, items;
! 422:
! 423: fprintf(fp, "%s(", AESName_10[code]);
! 424:
! 425: items = 0;
! 426: /* there are so few of these that linear search is fine */
! 427: for (i = 0; i < ARRAYSIZE(AESStrings); i++)
! 428: {
! 429: /* something that can be shown? */
! 430: if (AESStrings[i].code == opcode)
! 431: {
! 432: items = AESStrings[i].count;
! 433: break;
! 434: }
! 435: }
! 436: /* addrin array size in longs enough for items? */
! 437: if (items > 0 && items <= STMemory_ReadWord(AESControl+SIZE_WORD*3))
! 438: {
! 439: const char *str;
! 440: fputs("addrin: ", fp);
! 441: for (i = 0; i < items; i++)
! 442: {
! 443: if (first)
! 444: first = false;
! 445: else
! 446: fputs(", ", fp);
! 447: str = (const char *)STRAM_ADDR(STMemory_ReadLong(AESAddrin+SIZE_LONG*i));
! 448: fprintf(fp, "\"%s\"", str);
! 449: }
! 450: }
! 451: /* intin array size in words */
! 452: items = STMemory_ReadWord(AESControl+SIZE_WORD*1);
! 453: if (items > 0)
! 454: {
! 455: if (!first)
! 456: {
! 457: fputs(", ", fp);
! 458: first = true;
! 459: }
! 460: fputs("intin: ", fp);
! 461: for (i = 0; i < items; i++)
! 462: {
! 463: if (first)
! 464: first = false;
! 465: else
! 466: fputs(",", fp);
! 467: fprintf(fp, "0x%x", STMemory_ReadWord(AESIntin+SIZE_WORD*i));
! 468: }
! 469: }
! 470: fputs(")\n", fp);
! 471: }
! 472: else
! 473: fputs("???\n", fp);
! 474: fflush(fp);
! 475: }
! 476:
! 477: /**
1.1.1.14 root 478: * If opcodes argument is set, show AES opcode/function name table,
479: * otherwise AES vectors information.
1.1.1.9 root 480: */
1.1.1.14 root 481: void AES_Info(Uint32 bShowOpcodes)
1.1 root 482: {
1.1.1.14 root 483: Uint16 opcode;
484:
485: if (bShowOpcodes)
1.1.1.9 root 486: {
1.1.1.14 root 487: for (opcode = 10; opcode < 0x86; opcode++)
488: {
489: fprintf(stderr, "%02x %-16s", opcode, AES_Opcode2Name(opcode));
490: if ((opcode-9) % 4 == 0) fputs("\n", stderr);
491: }
492: return;
1.1.1.9 root 493: }
1.1.1.14 root 494: if (!bVdiAesIntercept)
495: {
496: fputs("VDI/AES interception isn't enabled!\n", stderr);
497: return;
498: }
499: if (!AESControl)
500: {
501: fputs("No traced AES calls!\n", stderr);
502: return;
503: }
504: opcode = STMemory_ReadWord(AESControl);
505: if (opcode != AESOpCode)
506: {
507: fputs("AES parameter block contents changed since last call!\n", stderr);
508: return;
509: }
510:
511: fputs("Latest AES Parameter block:\n", stderr);
512: fprintf(stderr, "- Opcode: %3hd (%s)\n",
513: opcode, AES_Opcode2Name(opcode));
514:
515: fprintf(stderr, "- Control: %#8x\n", AESControl);
516: fprintf(stderr, "- Global: %#8x, %d bytes\n",
517: AESGlobal, 2+2+2+4+4+4+4+4+4);
1.1.1.16! root 518: fprintf(stderr, "- Intin: %#8x, %d words\n",
1.1.1.14 root 519: AESIntin, STMemory_ReadWord(AESControl+2*1));
1.1.1.16! root 520: fprintf(stderr, "- Intout: %#8x, %d words\n",
1.1.1.14 root 521: AESIntout, STMemory_ReadWord(AESControl+2*2));
522: fprintf(stderr, "- Addrin: %#8x, %d longs\n",
523: AESAddrin, STMemory_ReadWord(AESControl+2*3));
524: fprintf(stderr, "- Addrout: %#8x, %d longs\n",
525: AESAddrout, STMemory_ReadWord(AESControl+2*4));
1.1 root 526: }
527:
1.1.1.2 root 528:
1.1.1.13 root 529: /*-----------------------------------------------------------------------*/
1.1.1.14 root 530:
1.1.1.13 root 531: /**
532: * Map VDI call opcode/sub-opcode to a VDI function name
533: */
534: static const char* VDI_Opcode2Name(Uint16 opcode, Uint16 subcode)
535: {
536: static const char* names_0[] = {
537: "???",
538: "v_opnwk",
539: "v_clswk",
540: "v_clrwk",
541: "v_updwk",
542: "", /* 5: lots of sub opcodes */
543: "v_pline",
544: "v_pmarker",
545: "v_gtext",
546: "v_fillarea", /* sub-opcode 13: v_bez_fill with GDOS */
547: "v_cellarray",
548: "", /* 11: lots of sub opcodes */
549: "vst_height",
550: "vst_rotation",
551: "vs_color",
552: "vsl_type",
553: "vsl_width",
554: "vsl_color",
555: "vsm_type",
556: "vsm_height",
557: "vsm_color",
558: "vst_font",
559: "vst_color",
560: "vsf_interior",
561: "vsf_style",
562: "vsf_color",
563: "vq_color",
564: "vq_cellarray",
565: "vrq/sm_locator",
566: "vrq/sm_valuator",
567: "vrq/sm_choice",
568: "vrq/sm_string",
569: "vswr_mode",
570: "vsin_mode",
571: "???", /* 34 */
572: "vql_attributes",
573: "vqm_attributes",
574: "vqf_attributes",
575: "vqt_attributes",
576: "vst_alignment"
577: };
578: static const char* names_100[] = {
579: "v_opnvwk",
580: "v_clsvwk",
581: "vq_extnd",
582: "v_contourfill",
583: "vsf_perimeter",
584: "v_get_pixel",
585: "vst_effects",
586: "vst_point",
587: "vsl_ends",
588: "vro_cpyfm",
589: "vr_trnfm",
590: "vsc_form",
591: "vsf_udpat",
592: "vsl_udsty",
593: "vr_recfl",
594: "vqin_mode",
595: "vqt_extent",
596: "vqt_width",
597: "vex_timv",
598: "vst_load_fonts",
599: "vst_unload_fonts",
600: "vrt_cpyfm",
601: "v_show_c",
602: "v_hide_c",
603: "vq_mouse",
604: "vex_butv",
605: "vex_motv",
606: "vex_curv",
607: "vq_key_s",
608: "vs_clip",
609: "vqt_name",
610: "vqt_fontinfo"
611: /* 131-233: no known opcodes
612: * 234-255: (Speedo) GDOS opcodes
613: */
614: };
615: static const char* names_opcode5[] = {
1.1.1.14 root 616: "<no subcode>",
1.1.1.13 root 617: "vq_chcells",
618: "v_exit_cur",
619: "v_enter_cur",
620: "v_curup",
621: "v_curdown",
622: "v_curright",
623: "v_curleft",
624: "v_curhome",
625: "v_eeos",
626: "v_eeol",
627: "vs_curaddress",
628: "v_curtext",
629: "v_rvon",
630: "v_rvoff",
631: "vq_curaddress",
632: "vq_tabstatus",
633: "v_hardcopy",
634: "v_dspcur",
635: "v_rmcur",
636: "v_form_adv",
637: "v_output_window",
638: "v_clear_disp_list",
639: "v_bit_image",
640: "vq_scan",
641: "v_alpha_text"
642: };
643: static const char* names_opcode5_98[] = {
644: "v_meta_extents",
645: "v_write_meta",
646: "vm_filename",
647: "???",
648: "v_fontinit"
649: };
650: static const char* names_opcode11[] = {
1.1.1.14 root 651: "<no subcode>",
1.1.1.13 root 652: "v_bar",
653: "v_arc",
654: "v_pieslice",
655: "v_circle",
656: "v_ellipse",
657: "v_ellarc",
658: "v_ellpie",
659: "v_rbox",
660: "v_rfbox",
661: "v_justified"
662: };
663:
664: if (opcode == 5)
665: {
666: if (subcode < ARRAYSIZE(names_opcode5)) {
667: return names_opcode5[subcode];
668: }
669: if (subcode >= 98) {
670: subcode -= 98;
671: if (subcode < ARRAYSIZE(names_opcode5_98)) {
672: return names_opcode5_98[subcode];
673: }
674: }
675: }
676: else if (opcode == 11)
677: {
678: if (subcode < ARRAYSIZE(names_opcode11)) {
679: return names_opcode11[subcode];
680: }
681: }
682: else if (opcode < ARRAYSIZE(names_0))
683: {
684: return names_0[opcode];
685: }
686: else if (opcode >= 100)
687: {
688: opcode -= 100;
689: if (opcode < ARRAYSIZE(names_100))
690: {
691: return names_100[opcode];
692: }
693: }
1.1.1.14 root 694: return "GDOS?";
1.1.1.13 root 695: }
696:
1.1.1.9 root 697: /**
1.1.1.14 root 698: * If opcodes argument is set, show VDI opcode/function name table,
699: * otherwise VDI vectors information.
1.1.1.9 root 700: */
1.1.1.14 root 701: void VDI_Info(Uint32 bShowOpcodes)
1.1 root 702: {
1.1.1.14 root 703: Uint16 opcode, subcode;
1.1 root 704:
1.1.1.14 root 705: if (bShowOpcodes)
1.1.1.9 root 706: {
1.1.1.14 root 707: Uint16 opcode;
708: for (opcode = 0; opcode < 0x84; )
709: {
710: if (opcode == 0x28)
711: {
712: fputs("--- GDOS calls? ---\n", stderr);
713: opcode = 0x64;
714: }
715: fprintf(stderr, "%02x %-16s",
716: opcode, VDI_Opcode2Name(opcode, 0));
717: if (++opcode % 4 == 0) fputs("\n", stderr);
718: }
719: return;
720: }
721: if (!bVdiAesIntercept)
722: {
723: fputs("VDI/AES interception isn't enabled!\n", stderr);
724: return;
725: }
726: if (!VDIControl)
727: {
728: fputs("No traced VDI calls!\n", stderr);
729: return;
730: }
731: opcode = STMemory_ReadWord(VDIControl);
732: if (opcode != VDIOpCode)
733: {
734: fputs("VDI parameter block contents changed since last call!\n", stderr);
735: return;
736: }
1.1 root 737:
1.1.1.14 root 738: fputs("Latest VDI Parameter block:\n", stderr);
739: subcode = STMemory_ReadWord(VDIControl+2*5);
740: fprintf(stderr, "- Opcode/Subcode: %hd/%hd (%s)\n",
741: opcode, subcode, VDI_Opcode2Name(opcode, subcode));
742: fprintf(stderr, "- Device handle: %d\n",
743: STMemory_ReadWord(VDIControl+2*6));
744: fprintf(stderr, "- Control: %#8x\n", VDIControl);
745: fprintf(stderr, "- Ptsin: %#8x, %d co-ordinate word pairs\n",
746: VDIPtsin, STMemory_ReadWord(VDIControl+2*1));
747: fprintf(stderr, "- Ptsout: %#8x, %d co-ordinate word pairs\n",
748: VDIPtsout, STMemory_ReadWord(VDIControl+2*2));
749: fprintf(stderr, "- Intin: %#8x, %d words\n",
750: VDIIntin, STMemory_ReadWord(VDIControl+2*3));
751: fprintf(stderr, "- Intout: %#8x, %d words\n",
752: VDIIntout, STMemory_ReadWord(VDIControl+2*4));
753: }
1.1 root 754:
1.1.1.14 root 755: #else /* !ENABLE_TRACING */
756: void AES_Info(Uint32 bShowOpcodes)
757: {
758: fputs("Hatari isn't configured with ENABLE_TRACING\n", stderr);
759: }
760: void VDI_Info(Uint32 bShowOpcodes)
761: {
762: fputs("Hatari isn't configured with ENABLE_TRACING\n", stderr);
763: }
764: #endif /* !ENABLE_TRACING */
765:
766:
767: /*-----------------------------------------------------------------------*/
768: /**
769: * Return true for only VDI opcodes that need to be handled at Trap exit.
770: */
771: static inline bool VDI_isWorkstationOpen(Uint16 opcode)
772: {
773: if (opcode == 1 || opcode == 100)
774: return true;
775: else
776: return false;
777: }
778:
779: /**
780: * Check whether this is VDI/AES call and see if we need to re-direct
781: * it to our own routines. Return true if VDI_Complete() function
782: * needs to be called on OS call exit, otherwise return false.
783: *
784: * We enter here with Trap #2, so D0 tells which OS call it is (VDI/AES)
785: * and D1 is pointer to VDI/AES vectors, i.e. Control, Intin, Ptsin etc...
786: */
787: bool VDI_AES_Entry(void)
788: {
789: Uint16 call = Regs[REG_D0];
790: Uint32 TablePtr = Regs[REG_D1];
1.1.1.12 root 791:
1.1.1.13 root 792: #if ENABLE_TRACING
1.1.1.14 root 793: /* AES call? */
794: if (call == 0xC8)
1.1.1.13 root 795: {
1.1.1.14 root 796: if (!STMemory_ValidArea(TablePtr, 24))
797: {
798: Log_Printf(LOG_WARN, "AES call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 24);
799: return false;
800: }
801: /* store values for debugger "info aes" command */
802: AESControl = STMemory_ReadLong(TablePtr);
803: AESGlobal = STMemory_ReadLong(TablePtr+4);
804: AESIntin = STMemory_ReadLong(TablePtr+8);
805: AESIntout = STMemory_ReadLong(TablePtr+12);
806: AESAddrin = STMemory_ReadLong(TablePtr+16);
807: AESAddrout = STMemory_ReadLong(TablePtr+20);
808: AESOpCode = STMemory_ReadWord(AESControl);
1.1.1.16! root 809: if (LOG_TRACE_LEVEL(TRACE_OS_AES))
! 810: {
! 811: AES_OpcodeInfo(TraceFile, AESOpCode);
! 812: }
1.1.1.14 root 813: /* using same special opcode trick doesn't work for
814: * both VDI & AES as AES functions can be called
815: * recursively and VDI calls happen inside AES calls.
816: */
817: return false;
1.1.1.13 root 818: }
819: #endif
1.1.1.14 root 820:
821: /* VDI call? */
822: if (call == 0x73)
823: {
824: if (!STMemory_ValidArea(TablePtr, 20))
825: {
826: Log_Printf(LOG_WARN, "VDI call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 20);
827: return false;
828: }
829: /* store values for extended VDI resolution handling
830: * and debugger "info vdi" command
831: */
832: VDIControl = STMemory_ReadLong(TablePtr);
833: VDIIntin = STMemory_ReadLong(TablePtr+4);
834: VDIPtsin = STMemory_ReadLong(TablePtr+8);
835: VDIIntout = STMemory_ReadLong(TablePtr+12);
836: VDIPtsout = STMemory_ReadLong(TablePtr+16);
837: VDIOpCode = STMemory_ReadWord(VDIControl);
838: #if ENABLE_TRACING
839: {
840: Uint16 subcode = STMemory_ReadWord(VDIControl+2*5);
841: LOG_TRACE(TRACE_OS_VDI, "VDI call %3hd/%3hd (%s)\n",
842: VDIOpCode, subcode,
843: VDI_Opcode2Name(VDIOpCode, subcode));
844: }
845: #endif
846: /* Only workstation open needs to be handled at trap return */
847: return bUseVDIRes && VDI_isWorkstationOpen(VDIOpCode);
848: }
849:
850: LOG_TRACE((TRACE_OS_VDI|TRACE_OS_AES), "Trap #2 with D0 = 0x%hX\n", call);
851: return false;
852: }
853:
854:
855: /*-----------------------------------------------------------------------*/
856: /**
857: * Modify Line-A structure for our VDI resolutions
858: */
859: void VDI_LineA(Uint32 linea, Uint32 fontbase)
860: {
861: if (bUseVDIRes)
862: {
1.1.1.16! root 863: int cel_ht = STMemory_ReadWord(linea-46); /* v_cel_ht */
1.1.1.14 root 864: STMemory_WriteWord(linea-44, (VDIWidth/8)-1); /* v_cel_mx (cols-1) */
1.1.1.16! root 865: STMemory_WriteWord(linea-42, (VDIHeight/cel_ht)-1); /* v_cel_my (rows-1) */
! 866: STMemory_WriteWord(linea-40, cel_ht*((VDIWidth*VDIPlanes)/8)); /* v_cel_wr */
1.1.1.14 root 867:
868: STMemory_WriteWord(linea-12, VDIWidth); /* v_rez_hz */
869: STMemory_WriteWord(linea-4, VDIHeight); /* v_rez_vt */
870: STMemory_WriteWord(linea-2, (VDIWidth*VDIPlanes)/8); /* bytes_lin */
871: STMemory_WriteWord(linea+0, VDIPlanes); /* planes */
872: STMemory_WriteWord(linea+2, (VDIWidth*VDIPlanes)/8); /* width */
873: }
874: LineABase = linea;
875: FontBase = fontbase;
876: }
877:
878:
879: /*-----------------------------------------------------------------------*/
880: /**
881: * This is called on completion of a VDI Trap workstation open,
882: * to modify the return structure for extended resolutions.
883: */
884: void VDI_Complete(void)
885: {
886: /* right opcode? */
887: assert(VDI_isWorkstationOpen(VDIOpCode));
888: /* not changed between entry and completion? */
889: assert(VDIOpCode == STMemory_ReadWord(VDIControl));
890:
891: STMemory_WriteWord(VDIIntout, VDIWidth-1); /* IntOut[0] Width-1 */
892: STMemory_WriteWord(VDIIntout+1*2, VDIHeight-1); /* IntOut[1] Height-1 */
1.1.1.16! root 893: STMemory_WriteWord(VDIIntout+13*2, 1 << VDIPlanes); /* IntOut[13] #colors */
1.1.1.14 root 894: STMemory_WriteWord(VDIIntout+39*2, 512); /* IntOut[39] #available colors */
895:
896: STMemory_WriteWord(LineABase-0x15a*2, VDIWidth-1); /* WKXRez */
897: STMemory_WriteWord(LineABase-0x159*2, VDIHeight-1); /* WKYRez */
898:
899: VDI_LineA(LineABase, FontBase); /* And modify Line-A structure accordingly */
1.1 root 900: }
901:
1.1.1.2 root 902:
903: /*-----------------------------------------------------------------------*/
1.1.1.9 root 904: /**
905: * Save desktop configuration file for VDI, eg desktop.inf(TOS 1.04) or newdesk.inf(TOS 2.06)
906: */
1.1.1.8 root 907: static void VDI_SaveDesktopInf(char *pszFileName, const Uint8 *Script, long ScriptSize)
1.1 root 908: {
1.1.1.9 root 909: /* Just save file */
1.1.1.12 root 910: File_Save(pszFileName, Script, ScriptSize, false);
1.1 root 911: }
912:
1.1.1.2 root 913:
914: /*-----------------------------------------------------------------------*/
1.1.1.9 root 915: /**
916: * Modify exisiting ST desktop configuration files to set resolution(keep user settings)
917: */
1.1.1.5 root 918: static void VDI_ModifyDesktopInf(char *pszFileName)
1.1 root 919: {
1.1.1.9 root 920: long InfSize;
921: Uint8 *pInfData;
922: int i;
923:
924: /* Load our '.inf' file */
925: pInfData = File_Read(pszFileName, &InfSize, NULL);
926: if (pInfData)
927: {
928: /* Scan file for '#E' */
929: i = 0;
930: while (i < (InfSize-8))
931: {
932: if ((pInfData[i]=='#') && (pInfData[i+1]=='E'))
933: {
934: /* Modify resolution */
935: pInfData[i+7] = '1'+VDIRes;
936: break;
937: }
938:
939: i++;
940: }
941:
942: /* And save */
1.1.1.12 root 943: File_Save(pszFileName, pInfData, InfSize, false);
1.1.1.9 root 944: /* Free */
945: free(pInfData);
946: }
1.1 root 947: }
948:
1.1.1.2 root 949:
950: /*-----------------------------------------------------------------------*/
1.1.1.9 root 951: /**
952: * Modify (or create) ST desktop configuration files so VDI boots up in
953: * correct color depth
954: */
1.1.1.14 root 955: static void VDI_FixDesktopInf(void)
1.1 root 956: {
1.1.1.9 root 957: char *szDesktopFileName, *szNewDeskFileName;
1.1 root 958:
1.1.1.9 root 959: if (!GEMDOS_EMU_ON)
960: {
961: /* Can't modify DESKTOP.INF when not using GEMDOS hard disk emulation */
962: return;
963: }
964:
965: szDesktopFileName = malloc(2 * FILENAME_MAX);
966: if (!szDesktopFileName)
967: {
968: perror("VDI_FixDesktopInf");
969: return;
970: }
971: szNewDeskFileName = szDesktopFileName + FILENAME_MAX;
972:
973: /* Create filenames for hard-drive */
974: GemDOS_CreateHardDriveFileName(2, "\\DESKTOP.INF", szDesktopFileName, FILENAME_MAX);
975: GemDOS_CreateHardDriveFileName(2, "\\NEWDESK.INF", szNewDeskFileName, FILENAME_MAX);
976:
977: /* First, check if files exist(ie modify or replace) */
978: if (!File_Exists(szDesktopFileName))
979: VDI_SaveDesktopInf(szDesktopFileName,DesktopScript,sizeof(DesktopScript));
980: VDI_ModifyDesktopInf(szDesktopFileName);
981:
982: if (!File_Exists(szNewDeskFileName))
983: VDI_SaveDesktopInf(szNewDeskFileName,NewDeskScript,sizeof(NewDeskScript));
984: VDI_ModifyDesktopInf(szNewDeskFileName);
1.1.1.5 root 985:
1.1.1.9 root 986: free(szDesktopFileName);
1.1 root 987: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.