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