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